题目
for循环中,使用 var 或 let 声明 i 变量,会得到不同的结果
var arr = [];
for (var i = 0; i < 2; i++) {
      arr[i] = function () {
        console.log(i);
      }
}
arr[0]();
arr[1]();
输出:
 2
 2
var arr = [];
for (let i = 0; i < 2; i++) {
      arr[i] = function () {
        console.log(i);
      }
}
arr[0]();
arr[1]();
输出:
 0
 1
这是为什么?
解析
首先我们都知道 js 的全局作用域、局部作用域
全局作用域
var 声明在函数体外,属于全局作用域
 即意味着:
 全局只有一个 i 变量,且可以被影响
if (true) {
   var name = '123';
}
console.log(name);  // 输出 '123'
局部作用域
let 声明的变量,属于局部作用域
 即意味着:
 该变量在 { } 内是有效的
if (true) {
   let name = '123';
}
console.log(name);    // 没有定义
for 循环中 定义 var 发生了什么
每一轮循环,将 function 添加到数组,function 是
function () {
  console.log(i);
}
因为使用 var 定义 i 变量,所以全局只有一个 i
 因此每一轮循环,是全局的这一个 i 在增加
 当退出循环后,i = 2
最终执行
arr[0]()
arr[1]()
执行对应的函数
console.log(i);
所以输出:
2
2
所以关键是:
 函数是最后执行的,此时函数去找当前的全局变量 i ,是2

for 循环中 定义 let 发生了什么
红宝书上是这样形容的:因为使用 let 定义变量 i,每轮迭代循环时,JS引擎在后台会声明一个新的迭代变量
 所以:每个 console.log(i) ,引用的 i 都是不同的变量实例

最终执行函数时,使用自己块级作用域的变量 i
 所以输出为:
0
1
所以关键是:
 每次循环都会在自己的块级作用域 { } 有变量 i ,最终引用不同的变量实例


















