javascript - 为什么这个 for/setTimeout() 代码实际上输出从 0 到 9 的数字?

标签 javascript for-loop asynchronous closures settimeout

JavaScript 闭包的一个常见陷阱是 running setTimeout() from a for loop ,并期望计数器在每次迭代时传递不同的值,而实际上它在 setTimeout() 函数执行之前被分配最后一个值:

for (i = 0; i < 10; i++) {
  setTimeout(function () {
    console.log(i)
  }, 100);
}  // => prints "10" 10 times

对此的一个解决方案是使用立即调用函数表达式:

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

另一个是传递一个额外的callback argument to setTimeout() (在 IE<9 中不起作用):

for (i = 0; i < 10; i++) {
  setTimeout(function foo(n) {
    console.log(n)
  }, 100, i);
}

但是为什么下面最简单的代码会产生相同的结果(0, 1, 2, ... 9)?

for (var i = 0; i < 10; i++)
  setTimeout(console.log(i), 100);

最佳答案

出现这种明显令人惊讶的行为是因为 first parameter to setTimeout可以是函数也可以是字符串,后者被 eval() 编辑为代码。

因此 setTimeout(console.log(i), 100); 将立即执行 console.log(i),并返回 undefined。然后 setTimeout("", 100) 将被执行,并显示 NOP 100 毫秒后调用(或被引擎优化掉)。

关于javascript - 为什么这个 for/setTimeout() 代码实际上输出从 0 到 9 的数字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26285029/

相关文章:

javascript - onblur 和链接元素在 Chrome 中无法正常工作 - 在 IE 10 中正常

javascript - 验证数字 javascript 在 Chrome 中不起作用

c - 其间有代码的 for 循环的可变数量

javascript - 使用下划线创建 `option`

javascript - 在获取模型后渲染 Marionette 区域

python - 如何启用请求异步模式?

javascript - 在执行下一个代码之前, typescript 会等待循环完成吗?

javascript - Node JS - 从异步函数获取数据

javascript - 通过在 PhantomJS 中循环抓取多个 URL

java - 迭代并显示从文本文件中获取的二维数组中的值