为什么这个简单的 for 循环不能按预期工作

Why doesn't this simple for loop work as expected?

本文关键字:不能按 工作 循环 for 简单 为什么      更新时间:2023-09-26

人们可能会期望以下内容打印出abc

var i, rowName;
for (i = 0; i < 3; i++, rowName = ['a', 'b', 'c'][i]) {
    console.log(rowName);
}

然而,相反,它打印出undefinedbc。为什么?

澄清一下:我知道如何使这项工作;我好奇的是为什么上述方法不起作用。

它打印undefinedbc的原因是因为 for 循环的工作方式。

for (initialization; condition; final expression)

让我们分解一下你的 for 循环。

初始化i = 0

条件i < 3

最后的表达方式:i++, rowName = ['a', 'b', 'c'][i]

首次进入循环时,i设置为 0 。这是初始化步骤。然后检查条件步骤i < 3。这是在每次迭代之前完成的,以决定是否继续循环。每次循环后,将计算最终表达式。在您的示例中,在根据当前索引将rowName设置为等于['a', 'b', 'c']中的元素之前,您先递增i

在您的情况下,在第一次迭代中,rowName undefined,因为尚未计算最终表达式。此后的每次迭代都按照您的预期运行,因为之前已经计算了最终表达式。

如果你想做棘手的单行循环风格,"正确"的语法是:

var array = ['a', 'b', 'c'];
for (var i = 0, rowName; rowName = array[ i++ ]; ) {
    console.log(rowName);
}

请注意 for 循环声明的结束;。从技术上讲,;之后有一个空语句,这是您通常会i++的地方。

在这种情况下,for 循环的"条件"是利用 Javascript 赋值运算符。如果你有一些这样的代码:

var a;
if( a = 1 ) { // Note this is assignment = not comparison ==
    console.log('true');
}

它将记录"true"。为什么?因为在表达式内部,a = 1实际上返回11是"真实的",这意味着它在布尔上下文(如if语句(中计算为 true。

反之亦然,如果你的值是假的:

var a;
if( a = 0 ) {
    console.log('true');
}

它不会记录,因为a = 0返回 0(以及将 0 分配给 a (。0 是假的。

这种古怪的 for 循环语法仅适用于某些条件:

  • 如果任何数组元素是"假的"(nullundefined""等(,它将过早地终止循环,因为如上所述的运算符的工作方式。
  • 这假设您不关心循环索引i。对于循环的每次迭代,它将偏离 1,因为i++是在for之前执行的。也就是说,第一次执行for体时,i将为 1,而不是其声明的起始值 0。
  • 此模式的唯一好处是节省几个字节。由于上述两个陷阱,它通常不会在现实世界中使用。

我想你想要这个?

var i, rowName;
for (i = 0; i < 3; i++){
    rowName = ['a', 'b', 'c'][i];
    console.log(rowName);
}

您在循环的每一步都重新分配rowName,这很undefined开始。以下是您可以执行的操作:

for(var i=0,rowName=['a','b','c'],l=rowName.length; i<l; i++){
  console.log(rowName[i]);
}

或类似的东西:

var rowName = ['a', 'b', 'c'];
for(var i=0,l=rowName.length; i<l; i++){
  console.log(rowName[i]);
}

真正的问题是,for(assign; test; execute) 内部的第三个条件直到满足循环的一test才会execute。如果test失败execute永远不会发生。如果test通过execute则在循环的第一遍之后真正开始。