ES6新特性:使用 "let" 来定义JavaScript变量
2015年8月8日

ECMAScript 2015 (ES6) 提供了一种更加严谨的变量声明方法: let 用于取代之前的 varlet 声明的变量作用域为所处的块级内而不像 var 作用于整个函数体内。虽然 var 的使用是相当宽松的,但这种特性往往会带来许多意想不到的bug,尤其是在一个复杂的工程中。本文将比照 var 来介绍一下 let 的特性。

块级作用域

之前写JS代码时碰到 if 内要声明变量总是纠结在 if 内直接声明呢还是在上一层函数内声明,有了 let, 终于可以像写 c# 一样愉快地在 if 块内声明变量了。

function foo() {
  if (true) {
    var a = 4; // 作用域为 foo 函数体内
    let b = 5; // 作用域为 if{} 内
    console.log(a); // 4
    console.log(b); // 5
  }
}
console.log(a); // 4
console.log(b); // 无法访问

再来看看下面这段代码,是否曾经也困惑过为何点击每个button都alert同一个数字?

var buttonList = document.getElementsByTagName('button');
for (var i = 0; i < buttonList.length; i++) {
    buttonList[i].onclick = function() {
        alert(i);
    }
}

有了 let,再也不需要用什么匿名函数传参来解决这类问题了,因为用 let 声明的变量 i 只作用于循环体内部。

var buttonList = document.getElementsByTagName('button');
for (let i = 0; i < buttonList.length; i++) {
    buttonList[i].onclick = function() {
        alert(i);
    }
}

先声明,后使用

ES6中,let 不再像 var 那样具有变量提升的特性了,如果代码块内存在 let 声明的变量,凡在声明语句前引用该变量,就会返回___引用错误___,因为从代码块内起始处至该 let 声明处,这个变量就会处于一个特殊区域,叫做: “临时死区” (temporal dead zone)。

if (true) {
  console.log(a); // ReferenceError
  let a = 3;
}

禁止重复声明

ES6规定 let 不能重复声明一个变量。

if (true) {
  let a = 1;
  let a = 2; // TypeError
}

可用性

  • Chrome 41.0 +
  • Firefox 39 +
  • Internet Explorer 11
  • io.js 3.0.0 +
  • Microsoft Edge
  • Node.js 0.11 + (需开启Harmony flag)

分类

JavaScript ES6