【问题标题】:What is the exact order of execution of Javascript's for loop?Javascript for 循环的确切执行顺序是什么?
【发布时间】:2015-04-16 02:52:59
【问题描述】:

在 Codepen 中,我正在使用的特定 for 循环的确切执行顺序让我有些困惑。看看这两个循环,它们都做同样的事情:

var a = ['orange','apple']; 
for (var i=0; i<2;i++) {
    alert(a[i]);
}

for (var j=0, fruit; fruit = a[j++];) {
    alert(fruit);
}

你可以在这里看到这个:http://codepen.io/nickbarry/pen/MYNzLP/

第一个循环是标准的、普通的 for 循环编写方式。正如预期的那样,它会提示“orange”,然后是“apple”。

我使用 MDN 的建议编写了第二个循环(在此处搜索“idiom”:https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)。

它有效,但我不太明白为什么。我对 for 循环的理解,这在某些方面显然是不正确的(不止一种方式?)是: * for 循环在第一次运行之前评估第二个表达式的真实性。所以似乎当 for 循环评估第二个表达式的真实性时,它应该在设置 fruit 的值之前增加 j。所以第一次通过循环,水果应该等于“苹果”。 * 并且循环应该只运行一次,因为在第一次通过之后,当它再次评估第二个表达式以查看它是否仍然为真时,它应该再次增加 j 之前它返回一个值给fruit,因为没有值在索引位置 2,它应该返回一个错误的结果,并退出循环。

我不明白到底发生了什么。在计算第二个表达式之前,for 循环是否运行一次?但这似乎是不可能的,因为如果发生这种情况,警报将不会在第一次发出任何警报,因为水果还没有价值。

另外,MDN 文章的作者似乎喜欢第二种编写循环的方式——有什么理由更好吗?我猜它使用的字符更少,这很好。跳过 for 循环中的第三个表达式是否可以节省大量时间?还是只是“它很酷,因为它很聪明”之类的东西?

【问题讨论】:

  • 它起作用的原因是它是一个后增量,而不是一个前增量。如果是 ++j 而不是 j++,您的假设将是正确的。
  • 如果你的目标是制造敌人,那么第二种编写循环的方式非常好。没有真正的好处,它更难阅读,如果数组中有错误的值,它会过早停止并且它可能更慢(尽管需要测试来确定)。
  • 请注意,MDN 是一个 wiki。任何傻瓜都可以添加内容。同一篇文章实际上建议 for-in 用于数组,但没有完整解释可能遇到的所有问题。
  • 我想指出一个for循环是有效的,只要它具有以下结构for(; ; ){}。 JS 不在乎这些分号之间的内容,但它们必须存在。您的循环不起作用,因为您正在尝试使用无效的索引 -1。循环在第一次迭代本身失败并且不会继续。
  • 如果您真的想知道应该如何评估for,请查看规范:ecma-international.org/ecma-262/5.1/#sec-12.6.3

标签: javascript loops for-loop


【解决方案1】:
for (var j=0, fruit; fruit = a[j++];) {
    alert(fruit);
}

在伪代码中等于:

initialize j = 0 and fruit = undefined

assign fruit = a[j] (j = 0, fruit = 'orange')
j = j + 1 (j = 1)
check fruit for being truthy (true)

alert(fruit) ('orange')

assign fruit = a[j] (j = 1, fruit = 'apple')
j = j + 1 (j = 2)
check fruit for being truthy (true)

alert(fruit) ('apple')

assign fruit = a[j] (j = 2, fruit = undefined)
j = j + 1 (j = 3)
check fruit for being truthy (false)

exit loop

重要提示:

后缀一元 ++ 运算符的作用如下:

  1. 我们返回变量的当前值
  2. 我们增加变量的值

跳过 for 循环中的第三个表达式是否可以节省大量时间?

它根本不保存任何东西

另外,MDN 文章的作者似乎喜欢第二种编写循环的方式——有什么理由更好吗?

无论如何都不是更好。作者只是认为它很酷,而作者喜欢很酷(虽然他们不是)。

【讨论】:

    【解决方案2】:

    for 循环实际上只是编写 while 循环的一种简写方式。 例如这个循环

    for(var i = 0, j = 10; i < 10; i++, j++) {
      alert(i + ", " + j);
    }
    

    只是一种较短的写作方式

    var i = 0, j = 10;
    while(i < 10) {
      alert(i + ", " + j);
      i++; j++;
    }
    

    这样就完成了这个循环

    for(var j=0, fruit; fruit = a[j++];) {
        alert(fruit);
    }
    

    和这个一样

    var j = 0, fruit;
    while(fruit = a[j++]) {
      alert(fruit);
    }
    

    【讨论】:

      【解决方案3】:

      您可以使用SlowmoJS 遵循JavaScript 的for 循环的执行顺序:http://toolness.github.io/slowmo-js/

      主页已经将for 循环加载到控制台中用于演示目的,但您可以根据自己的需要评估任何代码的操作顺序。

      【讨论】:

        猜你喜欢
        • 2018-03-24
        • 1970-01-01
        • 1970-01-01
        • 2022-12-17
        • 2013-07-26
        • 1970-01-01
        • 2015-01-29
        • 2013-01-04
        • 2016-08-20
        相关资源
        最近更新 更多