程序员Web前端之路首页投稿(暂停使用,暂停投稿)

深入剖析let/const在for循环中的作用原理

2017-03-17  本文已影响270人  e042cbe4da21

1、先来看一个例子

var a=[];  
for(var i = 0;i<3;i++){   
   a[i]=function(){console.log(i)}  
}
a[1](); //3
a[2](); //3

2、再来看一下For循环的过程

for (语句 1; 语句 2; 语句 3)
{
  被执行的代码块
}
// 语句 1 在循环(代码块)开始前执行
// 语句 2 定义运行循环(代码块)的条件
// 语句 3 在循环(代码块)已被执行之后执行

3、例子for循环执行过程伪代码如下:

var a=[]
var i = 0;

if(i<3) {
  a[i]=function(){console.log(i)}  
}
i++;

if(i<3) {
  a[i]=function(){console.log(i)}  
}
i++;

if(i<3) {
  a[i]=function(){console.log(i)}  
}
i++;

/* 数组a此时的状态
a = [
  function(){console.log(i)},
  function(){console.log(i)},
  function(){console.log(i)}
]
*/

// a[1] = function(){console.log(i)}

a[1](); // 打印3,因为i现在的值是3

注:“i现在的值是3”这句话在某种意义上是不准确的,
从作用域链的角度来说a[1]在它的if{}块作用域内没有找到i,
要去上一级作用域局部作用域中找,这时候找到了i,
而局部作用域中i现在的值是3。

4、如果把for循环的var换成let

var a=[];  
for(let i = 0;i<3;i++){   
   a[i]=function(){console.log(i)}  
}
a[1](); //1

// 执行过程
var a=[]
let i = 0;

if(i<3) {
    let i = i;
    a[i]=function(){console.log(i)}  
}
i++;

if(i<3) {
    let i = i;
    a[i]=function(){console.log(i)}  
}
i++;

if(i<3) {
    let i = i;
    a[i]=function(){console.log(i)}   
}
i++;

// console.log(i)在其块级作用域内就找到了i,
每次for循环把当前i值存入块级作用域。
所以a[1]()会打印1;
上一篇 下一篇

猜你喜欢

热点阅读