ECMAScript 2015 (ES6) 提供了一种更加严谨的变量声明方法: let 用于取代之前的 var。 let 声明的变量作用域为所处的块级内而不像 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)