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/

相关文章:

kotlin - 如何在 kotlin 中创建自定义迭代器并添加到现有类中?

java - MediaPlayer 的 WiFi 连接丢失时没有错误事件

javascript - CSS:使用左列流动(填充所有剩余空间)和右列固定(200px)制作两列布局

javascript - 如何在 Angular.js 中使用嵌套模板?

javascript - 数据关闭 : How to dismiss bootstrap modal inside function

java - java for 循环嵌套大于或等于

javascript - 将计时器转换为 react

python - 为什么捕获 StopIteration 时无法跳出循环?

c# - 运行异步 Foreach 循环 C# async await

c# - 这两个异步函数之间的区别