Why does this for / setTimeout() code actually output the numbers from 0 to 9?
JavaScript闭包的常见缺陷是从
1 2 3 4 5 | for (i = 0; i < 10; i++) { setTimeout(function () { console.log(i) }, 100); } // => prints"10" 10 times |
对此的一个解决方案是立即调用函数表达式:
1 2 3 4 5 6 | for (i = 0; i < 10; i++) (function(j) { setTimeout(function foo() { console.log(j) }, 100); })(i); // prints 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 |
另一种方法是将一个额外的回调参数传递给
1 2 3 4 5 | for (i = 0; i < 10; i++) { setTimeout(function foo(n) { console.log(n) }, 100, i); } |
但为什么以下最简单的代码产生相同的结果(
1 2 | for (var i = 0; i < 10; i++) setTimeout(console.log(i), 100); |
出现这种明显令人惊讶的行为是因为
所以
why does the following, simplest, code, produce the same result (0, 1,
2, ... 9)?
1
2 for (var i = 0; i < 10; i++)
setTimeout(console.log(i), 100);
因为它实际上没有。如果仔细观察,您会注意到日志消息在出现在控制台中之前不需要十分之一秒。通过立即调用
1 2 3 4 | for (var i = 0; i < 10; i++) { console.log(i); setTimeout(undefined, 100); } |
如果在所有代码段中替换
只是为了笑容,你可以做的另一件事(当你有
1 2 3 4 5 6 | for (i = 0; i < 10; i++) { setTimeout(function () { var i = +this; console.log(i) }.bind(i), 100); } |
比IIFE少一点点混乱。