美文网首页
ES6里的let声明和const声明

ES6里的let声明和const声明

作者: 阿走_ | 来源:发表于2017-05-17 18:22 被阅读0次

    let声明

    1. ES6新增了let来声明变量,用法类似于var,但声明的变量,只在let命令所在的代码块内有效。也不同于var声明的变量“提升”现象(变量在声明前使用,值为undefined)。let所声明的变量一定要在声明后使用,不然会报错。
    {
      let a = 10;
      var b = 1;    
    }   
      alert(b);  // 1
      alert(a);  // a is not defind
    
    
    console.log(foo); // 输出undefined
    var foo = 2;
    
    console.log(bar); // 谷歌下undefined
    let bar = 2;
    
    

    2.块级作用域内存在let所声明的变量会绑定在这个块级作用域内,外部影响不了。在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。

    var tmp = 123;
      if (true) {   
        tmp = 'abc';
        let tmp;
        alert(tmp);  //undefind  
    
        let str = 'ABC';
        alert(str); //ABC
        }
    
    

    上面代码中,存在全局变量tmp,但是块级作用域内let又声明了一个局部变量tmp,导致后者绑定这个块级作用域,所以在let声明变量前,对tmp赋值会undefined。须把let变量声明在前。

    3.let不允许在相同作用域内,重复声明同一个变量。

    function test(){
      var a = 10;
      var a = 1;  
    }
    function test(){
       let a = 10;
       var a = 1;  //Duplicate declaration "a"
    }
    function test(){
      let a = 10;
      let a = 1;  //Duplicate declaration "a"
    }
    

    4.let实际上为 JavaScript 新增了块级作用域,内层作用域可以定义外层作用域的同名变量,外层作用域无法读取内存作用域的变量

    (function() {
      var n = 5;
      if (true) {
        var n = 10;
        var m =100;
      }
     alert(n);  // 10 
     alert(m);  // 100
    })();
    
    (function() {
      let n = 5;
      if (true) {
        let n = 10; //内层作用域可以定义外层作用域的同名变量
        let m =100;
      }
     alert(n);      // 5 
     alert(m);      // m is not defined
    })();
    

    由上面可以看出varlet的不同,let外层代码块不受内层代码块的影响。内层作用域可以定义外层作用域的同名变量,外层作用域无法读取内存作用域的变量,所以m才会not defined。ES6还允许块级作用域的任意嵌套,例如:
    {{{{{let insane = 'Hello World'}}}}};

    5.ES6明确允许在块级作用域之中声明函数,ES6 规定,块级作用域之中,函数声明语句的行为类似于let,在块级作用域之外不可引用。

    (function(){
        if(true){
            function func(){
                alert("我被执行了");
                }
            func();   // 我被执行了      
        }
        func();        // ES6环境下func is not defined 但是ES5环境下弹出"我被执行了"
    })();
    

    上面代码在 ES5 中运行,会得到“我被执行了”,因为在if内声明的函数func会被提升到函数头部,但是在ES6环境中,块级作用域内声明的函数类似于let,对作用域之外没有影响。

    const声明

    const声明一个只读的常量。一旦声明,要立即初始化,不能留到以后赋值。初始化后的常量的值不能改变。

    const name = 'perter';
    console.log(name);  //perter
    
    name = 'Tom';       //"name" is read-only
    

    只声明不赋值:const name ; //Unexpected token

    ** const和let相同之处:**

    • 只在声明所在的块级作用域内有效;
    • 声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用;
    • 声明的常量一样不可重复声明

    const的本质不是保证变量的值不变,而是要保证指向的那个内存地址是不得改动的,这就是常量。对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针,这个指针式固定不可变的,但数据结构可以。

    如我用一个常量声明一个对象,常量保存的是指向这个对象的指针,对象属性的重写或添加是被允许的,但不能再把这个常量指向另一个对象:

    const obj = {
        name: '张三',
        age:20  
    }
    console.log(obj.name);   //张三
    
    obj.name = '李四';
    console.log(obj.name);   //李四
        
    obj = { name: '张三'};    //"obj" is read-only
    

    如果要让属性也不能再重写或添加可以用Object.freeze方法,将常量obj指向一个冻结的对象:

    const obj = Object.freeze({});
    obj.name = '张三';     //Cannot add property name, object is not extensible
    

    相关文章

      网友评论

          本文标题:ES6里的let声明和const声明

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