Javascript 为什么';这对循环工作来说不是很简单吗?

Javascript 为什么';这对循环工作来说不是很简单吗?,javascript,loops,Javascript,Loops,人们可能希望打印出a,b,c var i, rowName; for (i = 0; i < 3; i++, rowName = ['a', 'b', 'c'][i]) { console.log(rowName); } var i,rowName; 对于(i=0;i

人们可能希望打印出
a
b
c

var i, rowName;
for (i = 0; i < 3; i++, rowName = ['a', 'b', 'c'][i]) {
    console.log(rowName);
}
var i,rowName;
对于(i=0;i<3;i++,rowName=['a','b','c'][i]){
console.log(rowName);
}
但是,它会打印出
未定义的
b
c
。为什么?

澄清:我知道如何使这项工作;我想知道的是为什么上面的方法不起作用。

我想你想要这个

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

它打印
未定义的
b
c
的原因在于a的工作方式

让我们来分解你的for循环

初始化:
i=0

条件:
i<3

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


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


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

您在循环的每一步都重新指定了
rowName
,并且它是
未定义的
。以下是您可以做的:

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

for(var i=0,rowName=['a','b','c'],l=rowName.length;i如果要执行复杂的单行循环样式,“正确”语法是:

var array = ['a', 'b', 'c'];
for (var i = 0, rowName; rowName = array[ i++ ]; ) {
    console.log(rowName);
}
注意
循环声明的
的结尾
。从技术上讲,
后面有一个空语句,这是通常执行
i++
的地方

在本例中,for循环的“条件”利用了Javascript赋值运算符

var a;
if( a = 1 ) { // Note this is assignment = not comparison ==
    console.log('true');
}
记录为“true”。为什么?因为在表达式内部,
a=1
实际上返回
1
1
是“truthy”,这意味着它在类似
if
语句的布尔上下文中计算为true

反之亦然,如果您的值为假:

var a;
if( a = 0 ) {
    console.log('true');
}
它不会记录,因为
a=0
返回0(以及将0分配给
a
),而0为假

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

  • 如果任何数组元素为“false”(
    null
    未定义的
    ,等等),它将提前终止循环,因为操作符的工作方式如上所述
  • 这假设您不关心循环索引
    i
    。它将在循环的每次迭代中关闭1,因为
    i++
    for
    块之前执行。也就是说,您的
    for
    主体第一次执行时,
    i
    将是1,而不是其声明的起始值0
  • 这种模式的唯一好处是节省了几个字节。由于上述两个缺陷,它通常不会在现实世界中使用

最终表达式仅在每次循环迭代结束时计算。
rowName
在此之前未定义。请参见第3(和第2)条
for
循环中的表达式直到每次迭代结束时才进行求值。如果预先求值以分配
rowName
,它也会立即将
i
增加到
1
,跳过
0
的初始值。文档几乎不可能更清晰。它说“最终表达式在每次循环迭代结束时要计算的表达式。它发生在下一次条件计算之前。通常用于更新或递增计数器变量。”。因为对
rowname
的赋值发生在每次循环执行之后。因此,第一次通过时,
rowname
尚未赋值,因此您会得到
未定义的
(您可以将赋值移动到
循环头中的“中间”表达式。)OP的代码段试图单独记录每个值。这将记录整个数组,每次迭代。“在您的示例中,在设置
rowName
之前递增
i
”.True,但递增的
i
行名的赋值有什么关系?误导性。@PHPglue这怎么会误导人?我没有说两者都与另一个有关。但是,这两个语句恰好都是“最终表达式”或“后循环操作”,因此都在每个循环后进行计算。这可能会将OP混淆为重要的内容。@PHPglue混淆为重要的内容?在设置
rowName
之前增加
i
与for循环的第三部分直到第一次循环完成才执行这一事实无关。它只会使
i
启动第二次通过时,th
1
var a;
if( a = 1 ) { // Note this is assignment = not comparison ==
    console.log('true');
}
var a;
if( a = 0 ) {
    console.log('true');
}