解析经典面试题:for 循环中的 let var

更多文章可以看看我的博客:https://icheng.github.io/

题目

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 ,最终引用不同的变量实例

猜你喜欢

转载自blog.csdn.net/weixin_52268321/article/details/132564243
今日推荐