美文网首页
ES6块级作用域

ES6块级作用域

作者: 罂粟1995 | 来源:发表于2018-06-03 22:40 被阅读0次

    ES5中,没有块级作用域,所以会出现以下情况:

            var callbacks = [];
            for(var i=0;i<=2;i++){
              callbacks[i] = function(){
                return i * 2;
              }
            }
    
            console.table([
              callbacks[0](),
              callbacks[1](),
              callbacks[2](),
            ])
    

    这段代码的结果是输出3个6。

    首先var i=0这一句话,将i做了一个变量提升,i是一个跟callbacks平级的变量;
    然后进行for循环,for 循环结束时,i的值已经被更新成为了3;
    由于function(){return i*2}不是立即被调用的,而是循环结束后,也就是i等于3的时候才调用的,它执行的时候会去找它上一级作用域中i的值,发现i等于3,于是进行计算并输出,所以callbacks[0](),callbacks[1](),callbacks[2]()的结果全部都是6。

    ES6中我们可以用let来声明变量,将变量的作用域限定为块级作用域,不存在变量提升:

            const callbacks = [];
            for(let i=0;i<=2;i++){
              callbacks[i] = function(){
                return i * 2;
              }
            }
    
            console.table([
              callbacks[0](),
              callbacks[1](),
              callbacks[2](),
            ])
    

    结果为0,2,4。
    let声明的变量为块作用域,作用于当前块;每次循环都会把值保留下来供后面的闭包使用。
    这段for循环等价于:

    for (let i = 0; i < 10; i++) {
        a[i] = (function(i) {
            return function(){
              console.log(i);
           }
        })(i);
    }
    

    在ES6中只需一个花括号就可以指定块作用域。

    {
              function foo(){
                return 1;
              }
              console.log(foo() === 1);
    
              {
                function foo(){
                  return 2;
                }
                console.log(foo() === 2);
              }
    
              console.log(foo() === 1);
    }
    

    结果是打印3个true。
    可见两个作用域没有相互影响,一对花括号就已经把作用域隔离。

    相关文章

      网友评论

          本文标题:ES6块级作用域

          本文链接:https://www.haomeiwen.com/subject/vjsssftx.html