美文网首页
1. let , const 块级作用域

1. let , const 块级作用域

作者: wudimingwo | 来源:发表于2018-12-05 08:53 被阅读0次

    作用域
    全局作用域 => global
    函数作用域 => 因函数执行而产生的作用域

    块级作用域
    形式 : { }
    特点 : 在块级作用域内定义的变量只会在当前作用域下有效.
    暂时性死区(TDZ)
    不存在变量提升
    不允许重复定义


    image.png

    问题1 let x = x 是否会报错?

    let x => TDZ [x]
    先进行右边 x的取值操作, 报错.

    问题2 下面代码是否会报错?

    let x = 10;
    {
      let x = x;
    }
    

    跟问题1 是一样的道理.
    在当前作用域内声明 let x 的时候,
    跟上一级的x 就没任何关系了.

    问题3 下面代码是否会报错?
    会 , 同一个作用域下不允许 重复声明

    {
    let x = 1;
    let x = 2;
    }
    

    问题4 下面的代码是否会报错
    不会, 表明不是在同一作用域下重复声明
    表明 三个声明都在 不同作用域下,
    表明 for循环存在 3个块级作用域.
    这跟 var 有很大的区别.

    let i = 0;
    for(let i = 0;i < 10; i++) {
      let i
    }
    
    

    丁老师的模拟 ,

                let i = 111;
                {
                  let i = 0;
                  while (i++ < 10){
                    let i 
                  }
                  
                }
    

    经典闭包问题

                var arr = [];
                for(var i = 0 ; i < 10; i++){
                  arr[i] = function () {
                    console.log(i);
                  }
                }
                
                arr[5]();// 10
    

    出现这个问题的根本原因是,闭包.
    函数内部可以访问函数外部的变量.
    变量i的作用域是全局,在调用arr[5]时,
    i在全局的值为10
    经典解决方法,用闭包解决闭包.

                var arr = [];
                for(var i = 0 ; i < 10; i++){
                  (function (i) {
                    arr[i] = function () {
                        console.log(i);
                    }
                  })(i);
                }
                
                arr[5]();//5
    

    形式看起来有点复杂, 核心逻辑是,
    给每个i值 生成独立的函数作用域.
    而函数作用域只有在函数执行的时候,才会产生.
    同理也可以这样.

                var arr = [];
                function _loop (i) {
                    arr[i] = function () {
                      console.log(i);
                    }
                }
                for(var i = 0 ; i < 10; i++){
                    _loop(i);
                }
                
                arr[5]();//5
    

    每次i值有变化时,都执行函数, 形成专用的作用域.

    用let 解决闭包问题

                var arr = [];
                for(let i = 0 ; i < 10; i++){
                    arr[i] = function () {
                        console.log(i);
                    }
                }
                
                arr[5]();//5
    

    上面的代码表明,i值每次有变化时,都会生成一个作用域.
    所以可以这样模拟

          var arr = [];
          {
            let i = 0;
            while(i++ < 10) {
              let j = i;
              arr[j] = function() {
                console.log(j);
              }
            }
            arr[5]();
          }
    

    const 与 let 的区别是, const 只允许赋值一次,
    const 也有 TDZ
    不允许重复声明
    能够识别块级作用域.


    关于 let 一个补充
    似乎 let 定义的变量,默认不在 window?

    let a = 123;
    console.log(a);// 123
    console.log(window.a);// undifined
    

    块级作用域 也可以形成闭包, 完成变量私有化

          let fn = null; 
          {
            let a = 1;
            let b = 2;
            fn = () => {
              return a + b++
            }
            console.log(fn());/3
          }
    
          console.log(fn());/4
    

    相关文章

      网友评论

          本文标题:1. let , const 块级作用域

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