美文网首页
let 和 const

let 和 const

作者: CRJ997 | 来源:发表于2019-04-11 13:51 被阅读0次

    作用域

    在ES6之前,并没有块级作用域这种概念,有的只有函数作用域和全局作用域。然后变量的声明方式来讲,也就只有var。但是var 声明的变量由于存在变量提升这个机制,导致var声明的变量都会在整个作用域(整个函数作用域或者全局作用域)中可见。为了减少对作用域命名空间的污染和规避冲突,也就引入了let这个关键词。

    • 不过实际上通过try和with实际上是建立了块级作用域的,但是这个概念确实不普遍
    //例如使用with把一个对象的作用域扩展到当前作用域时,相当于一个块级作用域
    var a = 90;
    var obj = {
        a:8;
        b:10;
    };
    with(obj){   //这一部分就类似于块级作用域
      console.log(a);  //这边的a覆盖外部的a定义
      console.log(b);
    }
    console.log(a);//外部无法访问obj内部的a
    

    let 的使用

    和var的用法相同,但是并不存在变量提升。也就是下面的代码会导致Reference error错误

    console.log(a);// Uncaught ReferenceError: a is not defined  at index.html:9
    let a = 9;
    
    • 使用的注意事项
      当使用let关键字把变量绑定在一个已经存在的块作用域上的时候,这种行为是隐式的。在开发和修改代码的过程中,如果没有密切关注哪些块级作用域中有绑定的变量,并且习惯性地移动这些块或者将其包含在其他的块中,就会导致代码的混乱(实践不够不太理解...)

    比较有用的用法:

    1. 使垃圾回收没有顾虑
      考虑下面的代码,这些代码包含在一个函数作用域中的话
    function process(data){
         //do something
    }
    var someReallyBigData  = {....};
    processs(someReallyBigData);
    var btn = document.getElementById('myButton');
    btn.addEventListener('click',function click(event){
         console.log('button clicked');
    },false);
    

    click函数的点击回调并不需要someReallyBigData变量,理论上来讲这意味着当process(...)执行完成后,在内存中占用大量空间的数据结构就可以被垃圾回收了。但是,由于click函数形成了一个覆盖整个作用域的闭包,因此JS引擎极有可能仍然保存着这个结构(取决于具体实现)

    这时候可以这么做:
    用{}把这个比较大的数据结构括起来,用let定义someReallyBigData:

    function process(data){
         //do something
    }
    //这里声明块级作用域,就很显式的告诉垃圾回收机制,这个地方的内存在结束之后可以马上回收
    {
        let someReallyBigData  = {....};
        processs(someReallyBigData);
    }
    var btn = document.getElementById('myButton');
    btn.addEventListener('click',function click(event){
         console.log('button clicked');
    },false);
    

    垃圾回收机制也就没有顾虑了

    1. let 循环
      for循环中定义循环变量。
    for(let i=0;i<10;i++){
       console.log(i);
    }
    console.log(i); //Reference Error
    

    let在for循环中的作用:

    • 不仅仅把i绑定到for循环的块中,事实上它将其重新绑定到了循环的每一个迭代中,确保使用上一个循环迭代结束时的值重新进行赋值。(也就是循环的每一次都执行一次let i的重新声明)
      也就是上面的代码类似于下面
     {
       let j;
       for(j=0; j<10;j++){
           let i=j;   //每个迭代都重新绑定
          console.log(i);
       }
    }
    

    说说const

    1. 首先const创建的也是块级变量
    2. 正如其名,常量

    可以看看const定义和其ES5等效代码:

    //ES6
    const a = 10;
    
    //ES5
    Object.defineProperty(this,'a',{
         configurable:false,
         enumerable:true,
         writable: false,
         value: 10
    }
    

    相关文章

      网友评论

          本文标题:let 和 const

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