无法理解简单JavaScript代码输出结果:let循环变量配合setTimeout输出异常
function func2() { for (let i = 0; i < 3; i++) { setTimeout(() => console.log(i), 2000); } } func2();
结果差异的核心原因
你预期输出三个3的逻辑,适用于用var声明循环变量的场景,本次使用let声明触发了ES6为for循环定制的块级作用域绑定规则,因此最终输出为0、1、2。
具体执行逻辑
- 当
for循环的计数器使用let声明时,JS会为每一次循环迭代单独创建独立的块级作用域,每一轮迭代的i都是全新的独立变量,初始值为上一轮迭代结束后i的计算结果。 - 每一轮循环中定义的
setTimeout回调函数,作为闭包捕获的是当前迭代对应块级作用域内的i变量,三个回调分别绑定了三个不同的i,而非共享同一个顶层循环变量。 - 2秒后回调依次触发执行时,每个回调读取的都是自己绑定的独立
i的值,因此依次输出0、1、2。
对比验证
如果将代码中的let替换为var,就会得到你预期的三个3:var不存在块级作用域,三个回调会共享同一个函数作用域下的i变量,循环结束时i的值已经变为3,所有回调执行时读取的都是同一个i的最终值。
内容的提问来源于stack exchange,提问作者Daud
相关产品推荐
相关产品推荐

