ES6 let命令

let所声明的变量只在let命令所在的代码块内有效

1
2
3
4
5
6
{
    let foo = 10
    var bar = 20
}
console.log(foo) // Uncaught ReferenceError: foo is not defined
console.log(bar) // 20

for循环的计数器就非常适合使用let命令。

不存在变量提升

1
2
3
4
5
console.log(box1) // ReferenceError: box1 is not defined
let box1 = 10

console.log(box2) // undefined
var box2 = 20

使用var命令时,变量可以在声明之前使用,值为undefined,let命令改变了语法行为以纠正这种现象,它所声明的变量只有在声明后才能使用,否则会报错。

暂时性死区

1
2
3
4
5
6
7
8
9
10
11
12
13
// let的情况
var box = 1
if (true) {
    console.log(box) // VM356:3 Uncaught ReferenceError: box is not defined
    let box = 2
}

// var的情况
var box = 1
if (true) {
    console.log(box) // 1
    var box = 2
}

只要块级作用域内存在let命令,它所声明的变量就会绑定这个区域,不再受外部的影响。

上例中使用let的情况,虽然已经在全局作用域内声明并初始化了box变量,但在块级作用域内又使用let命令声明了一个局部的box变量,后者绑定了这个块级作用域,所以在let声明变量之前,任何对box的使用都会报错。

ES6规定,如果块级作用域中存在let和const命令,该块级作用域对这两个命令声明的变量从一开始就形成一个封闭的作用域,凡是在声明之前对这些变量的使用都会报错。这个现象在语法上称为“暂时性死区”。

不允许重复声明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 不报错
var box = 10
var box = 20

// Uncaught SyntaxError: Identifier 'foo' has already been declared
let foo = 10
let foo = 20

// Uncaught SyntaxError: Identifier 'foo' has already been declared
var bar = 10
let bar = 20

// Uncaught SyntaxError: Identifier 'foo' has already been declared
let fox = 10
var fox = 20

let命令不允许在同一作用域内重复声明同一变量。