为什么JavaScript闭包在两类let声明的for循环场景中表现不同?
两段for循环代码输出差异的核心原因
核心原因是 ES6 中 let 声明在 for 循环头部的块级绑定特殊规则,两段代码的变量i的作用域完全不同:
- 第一段代码中,
let i直接声明在for循环的头部:
JS引擎会为for循环的每一次迭代单独创建一个独立的i变量绑定,每一轮迭代的i都是互不干扰的独立块级变量。三次循环里注册的setTimeout箭头函数作为闭包,分别捕获了对应迭代轮次的独立i变量。等1秒后回调执行时,每个闭包拿到的都是当时绑定的对应值,因此输出0,1,2。
对应代码:for (let i = 0; i < 3; i++) { setTimeout(() => { console.log(i) }, 1000); } // 输出: 0, 1, 2 - 第二段代码中,
i声明在for循环的外层作用域:
整个for循环全程共用同一个外层作用域下的i变量,三次循环注册的setTimeout闭包捕获的都是同一个i的引用。等1秒后回调执行时,for循环早已执行完毕,此时共享的i已经被累加到3,因此三个回调输出的都是3,3,3。
对应代码:let i = 0; for (i = 0; i < 3; i++) { setTimeout(() => { console.log(i) }, 1000); } // 输出: 3, 3, 3
内容的提问来源于stack exchange,提问作者user12687104
相关产品推荐
相关产品推荐

