我一直在试图理解为什么以下代码片段的行为如下:
for (var i=1; i<=5; i++) {
setTimeout( function timer(){
console.log( i );
}, i*1000 );
} //prints 6 five times with a gap of one second in between each
为什么6?我看到了一些解释,但我仍然无法理解。另外为什么下面的代码有用?
for (var i=1; i<=5; i++) {
(function(){
var j = i;
setTimeout( function timer(){
console.log( j );
}, j*1000 );
})();
}
答案 0 :(得分:0)
你传递setTimeout()
相同的lambda五次,每次都引用同一个循环变量i
。对于每个调用,在循环退出后评估lambda,当i
等于6
(i++
时,检查i <= 5
是否为var j;
,如果没有,则退出循环)。
lambda引用了变量本身,而不是lambda创建时的值。这在大多数情况下非常有用。不是这个。
var j = i;
版本有两个 lambda。具有i
的那个会立即执行,其当前值为j
。这会创建一个新变量j
,该变量位于该lambda的本地。 i
初始化为setTimeout()
的值,该值是外部lambda执行时的当前值。所以在这种情况下,你给了j
你可以考虑的五个不同的lambda,有五个不同的变量,都是j
,但有五个不同的值。
内部lambda稍后执行,但它使用i
。
不同之处在于代码创建了一个唯一的位置来存储for (var i=1; i<=5; i++) {
var j = i;
setTimeout( function timer(){
console.log( j );
}, j*1000 );
}
的每个值。
最后一点:在其他一些语言中,这可行:
j
在JavaScript中,它没有。 j
的范围不同。在JavaScript中,在这种情况下只会有一个j
。这就是使用立即执行的函数的原因:确保有多个@Value
。