var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i); // i 指向全局的 i,也就是数组中函数全部的i都指向的是同一个变量i
};
}
a[6](); // 10
复制代码
上面代码中,变量i是var命令声明的,在全局范围内都有效,因此全局只有一个变量i。每一次循环,变量i的值都会自增,而循环内被赋给数组a的函数内部的console.log(i),里面的i指向的就是全局的i。也就是说,全部数组a的成员里面的i,指向的都是同一个i,致使运行时输出的是循环结束以后i的值,也就是 10。数组
若是使用let,声明的变量仅在块级做用域内有效,最后输出的是 6。闭包
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i); //因为 let 建立的变量是块级做用域的,因此在这个函数内每次都保存一个新的 i
};
}
a[6](); // 6
复制代码
这是由于let 建立的变量是块级做用域的,因此每次循环都是一个新的 i,每次的值都是 i++ 的结果。由于每次循环的 i 都是一个独立的变量(内存里的惟一地址),所以闭包记录的值都是惟一的,因此才能获得最终的结果函数
若是用 var 的话,变量 i 是一个全局变量,虽然循环体内每次都建立了一个函数来打印 i,可是当时当刻仅仅是一个指向全局变量 i 的指针,当循环结束以后不管你用哪个下标去访问循环建立的闭包函数,打印的变量 i 都是全局的那一个,因此所有都是 10。ui