美文网首页
let和const命令

let和const命令

作者: 黄小展Zane | 来源:发表于2017-12-25 14:58 被阅读10次

    1.let命令
    2.块级作用域
    3.const命令


    1.let命令

    1.用let声明变量,只在块级作用域有效

    在花括号{}内的变量对外部不可访问。

    {
      let a = 10;
    }
    a //a is not defined
    

    a 访问不到花括号{}内的 a 变量。

    for (let i = 0; i < 10; i++) { }
    
    console.log(i); //i is not defined
    

    i 访问不到for循环体内的 i 变量。

    for (let i = 0; i < 3; i++) {
      let i = 'abc';
      console.log(i);
    }
    // abc
    // abc
    // abc
    

    两个 i 在不同的作用域,()是父作用域,{}是子作用域,互不影响。

    2.不存在变量提升(Hoisting)

    // var 
    console.log(foo); // 输出undefined
    var foo = 2;
    // 实际是
    var foo;
    console.log(foo); // foo存在未赋值,输出undefined
    foo = 2;
    
    // let 
    console.log(bar); // bar不存在,直接报错 ReferenceError
    let bar = 2;
    

    3.暂时性死区(temporal dead zone,简称 TDZ)

    如果区块中存在let和const命令,这个区块就形成封闭作用域。不受外部影响。作用域内,在let声明变量前,该变量都是不可用的。

    if (true) {
      // TDZ开始
      tmp = 'abc'; // ReferenceError
      console.log(tmp); // ReferenceError
      console.log(typeof(tmp)); // ReferenceError
    
      let tmp; // TDZ结束
      console.log(tmp); // undefined
    
      tmp = 123;
      console.log(tmp); // 123
    }
    

    变量一定要在声明之后使用,否则就报错。

    4.不允许重复声明

    // 报错
    function func() {
      let a = 10;
      let a = 1;
    }
    

    2.块级作用域

    1.ES6中的块级作用域

    {{{{ // 1
      let insane = 123;
      {
        let insane = 'Hello World';// 2
        let abc = 'Hello World'
      }
      console.log(insane); // 123
      console.log(abc); // 报错 3
    }}}};
    
    • 1允许块级作用域任意嵌套
    • 2内层作用域可以定义外层作用域的同名变量
    • 3外层作用域无法读取内层作用域的变量
    // IIFE 写法
    (function () {
      var tmp = ...;
      ...
    }());
    
    // 块级作用域写法
    {
      let tmp = ...;
      ...
    }
    

    替代了立即执行函数表达式(IIFE)

    2.块级作用域与函数声明

    function f() { console.log('I am outside!'); }
    (function () {
      if (false) { // 1
        function f() { console.log('I am inside!'); } // 2 let f = () => {}
      }
      f();
    }());
    // Uncaught TypeError: f is not a function
    
    • 1允许在块级作用域之中声明函数

    • 2块级作用域内声明的函数类似于let,对作用域之外没有影响

    • 3但浏览器为了兼容旧代码,在实现行为上,规定函数声明类似于var,即会出现变量提升的效果(提升到全局作用域或函数作用域的头部)

    function f() { console.log('I am outside!'); }
    (function () {
      var f = undefined;
      if (false) {
        function f() { console.log('I am inside!'); } // 3 var 
      }
    
      f();
    }());
    // Uncaught TypeError: f is not a function
    

    解决方法:应该避免在块级作用域内声明函数,如果确实需要,也应该写成函数表达式,而不是函数声明语句。

    // 函数声明语句
    {
      let a = 'secret';
      function f() {
        return a;
      }
    }
    // 函数表达式
    {
      let a = 'secret';
      let f = function () {
        return a;
      };
    }
    

    3.do表达式 (还在ES7...的提案中)

    在块级作用域之前加上do,使它变为do表达式,然后就会返回内部最后执行的表达式的值。

    let x = do {
      let t = 1;
      t + 10;
    };
    // 11
    

    4.const命令

    const a = 1;
    a = 2; // error:Assignment to constant variable
    

    ▲const用来声明常量,常量的值不可改变。

    const foo;
    // SyntaxError: Missing initializer in const declaration
    

    ▲常量的声明必须先初始化,只声明不赋值,就会报错

    const的作用域、变量不提升、暂时性死区、不可重复声明,跟let一样。

    相关文章

      网友评论

          本文标题:let和const命令

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