ES6之let、const

ES6之let、const

在ES6中加入了两种变量的声明方式:

  • 可以改变的变量关键字:let
  • 不可以改变的变量关键字:const

letconstvar关键字的区别

letconst用于块级声明

  • 块级作用域(词法作用域)

    • 函数内部
    • 块中(字符{}之间的区域)
  • 在同一作用域不可以重复声明; 嵌套的作用域,可以同名。

   function exampleFunction () {  // 函数内部,一个块级区域
      let a = 1;
      const b = 1;
      
      if (true) {      // {}之间的块区域
        let a = 2;     // 合法
        const b =2;    // 合法
      }
   }

变量提升和TDZ

  • 变量提升:在函数作用域或全局作用域中通过关键字var声明的变量,无论是在哪里声明的,都会被当成在当前作用域顶部声明的变量。
   function varExample(flag) {
     if (flag) {
     	var a = 1;
     }
     console.log(a)  // flag 为 true,输出 1, 
                     // flag 为 false,输出 undefined,
   }
   
   实际js引擎会这样解析
   function varExample(flag) {
     var a;
     if (flag) {
       a = 1;
     }
     console.log(a)   // flag 为 false时,a已定义、但未赋值,因此返回 undefined.
   }
  • TDZ (Temporal Distortion Zone): 临时死区
    var声明的变量会发生变量提升,而letconst声明的变量会放在一个‘小黑屋’里。只会在变量声明之后,才能将变量放出来。

      function tdzFunction() {
        console.log(typeof a); // 还在TDZ内,访问报错,提示声明前不可访问
        let a = 1;
        console.log(typeof a); // 正常输入类型 number, 当然前面的报错要先屏蔽一下
      }
    
  • 特殊处理:循环中的块作用域绑定

    • var的循环,在其中使用立即调用表达式(IIFE)
      var func = [];
      for (var i = 0; i < 10; i++) {
      	funcs.push((function(value) {
     		return function() {     // 此处若不返回函数,push入数组的将是执行后的结果undefined
     			console.log(value);
     		}
     	}(i)));
      }
      funcs.forEach(function(func) {
      	func();  // 0, 1, 2, ... 9
      })
    
    • 使用let的循环
      var func = [];
      for (let i = 0; i < 10; i++) {
      	funcs.push(function() {
         	console.log(i)
         });
      }
    
    • 在每次循环时,let声明都会创建一个新变量i。
    // 伪代码
    (let i = 0) {
      funcs[0] = function() {
         console.log(i)
      }
    }
    (let i = 1) {
      funcs[1] = function() {
         console.log(i)
      }
    }(let i = 2) {
      funcs[2] = function() {
         console.log(i)
      }
    }
    ......
    
    • const 不能使用在普通的for循环中,因为i++时重新赋值会报错。
    • for-of、for-in循环中,key值是一种引用关系,因此与let用法一致。

babel 编译

在线实时编译地址:http://google.github.io/traceur-compiler/demo/repl.html

  • 我们可以看到,let在循环中声明时,代码块的内容被单独拎出来形成了一个闭包。

至此,let、const知识点整理完毕。


参考书籍:

《深入理解ES6》[美] NICHOLAS C. ZAKAS 著 刘振涛 译

原文地址:https://www.cnblogs.com/miku561/p/11720409.html