ES6: let vs var 在块作用域内用法区别

在js中let和var有个用法让人很疑惑,很多人搞了很久都没有搞懂,就是下面两个例子:

for (var i = 0; i < 10; i++) {
    setTimeout(function() {
       console.log(i); }, 100 * i);
}

输出结果:

for (let i = 0; i < 10; i++) {
    setTimeout(function() {
       console.log(i); }, 100 * i);
}

 输出结果:

上面两段代码的差别就是变量i声明的时候,第一段代码是var,第二段代码是let,就仅仅是这个差别,为什么导致结果差别这么大呢?

 为了方便解释,我在两段代码上分别加上了log,再看看输出结果:

for (var i = 0; i < 10; i++) {
    console.log("outside");
    setTimeout(function() {  
       console.log("inside"); 
       console.log(i); }, 100 * i);
}

 

for (let i = 0; i < 10; i++) {
    console.log("outside");
    setTimeout(function() {  
       console.log("inside"); 
       console.log(i); }, 100 * i);
}

 从上面的输出结果可以看出,这段代码是先将for循环全部执行完了之后再执行setTimeout的,差别就在这里。

对于用var声明的变量来说,是没有块级作用域的概念的,i在全局范围内有效,而全局只有一个i变量,每循环一次i就改变一次,到最后i = 10,再执行setTimeout时,i已经为10,所以输出的i为10;

而let声明的变量是有作用域的概念的,let声明的变量只在块级作用域有效,所以当前的i只在本轮循环有效,每次循环i其实都是一个新的变量,所以最后输出的会是0~9。

在不支持let的地方,上面的问题还有一种解法,就是立即执行函数,代码如下:

for (var i = 0; i < 10; i++) {
    console.log("outside");
    (function(i){
       setTimeout(function() {  
           console.log("inside"); 
           console.log(i); }, 100 * i);
    })(i);
}

欢迎大家指教~

原文地址:https://www.cnblogs.com/ycherry/p/8178265.html