先看阮大神的【ECMAScript 6 入门】中关于这一部分的描述
var a = []; for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 6
“上面代码中,变量i
是let
声明的,当前的i
只在本轮循环有效,所以每一次循环的i
其实都是一个新的变量,所以最后输出的是6
。你可能会问,如果每一轮循环的变量i
都是重新声明的,那它怎么知道上一轮循环的值,从而计算出本轮循环的值?这是因为 JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量i
时,就在上一轮循环的基础上进行计算。
另外,for
循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。”
以上是书中片段,按照他的解释,代码改写为如下
var a = []; for (let i = 0; i < 10; i++) { let k = i; a[k] = function () { console.log(k); }; } a[6](); // 6
简单理解,就相当于每次都隐式的声明了一个块级作用域的变量对应每次的循环。