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
启动第二次通过时,th1
。
var a;
if( a = 1 ) { // Note this is assignment = not comparison ==
console.log('true');
}
var a;
if( a = 0 ) {
console.log('true');
}