ES6之let和const

let

ES6新增了let命令,用于声明变量。使用类似于var,但是let命令会形成块级作用域。

特点

1.不存在变量提升

1
2
3
4
5
6
7
// var 的情况
console.log(foo); // 输出undefined
var foo = 2;

// let 的情况
console.log(bar); // 报错ReferenceError
let bar = 2;

2.暂时性死区
块级作用域内使用let声明的变量会被封锁在作用域内,不受外部影响,块级作用域内部无法访问外部作用域的同名变量。

1
2
3
4
5
6
var tmp = 123;

if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}

上面代码中,存在全局变量tmp,但是块级作用域内let又声明了一个局部变量tmp,导致后者绑定这个块级作用域,所以在let声明变量前,对tmp赋值会报错。

在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。

1
2
3
4
5
6
7
8
9
10
11
if (true) {
// TDZ开始
tmp = 'abc'; // ReferenceError
console.log(tmp); // ReferenceError

let tmp; // TDZ结束
console.log(tmp); // undefined

tmp = 123;
console.log(tmp); // 123
}

上面代码中,在let命令声明变量tmp之前,都属于变量tmp的“死区”。

3.不能重复声明
let不允许在相同作用域内重复声明同一变量。

const

const声明一个只读的常量。一旦声明,常量的值就不能改变。声明时必须初始化。
值不能改变的本质是变量的地址不能改变,如果是简单类型(数值、字符串、bool),地址存的就是值,等同于常量;如果是复杂类型(对象、数组),地址存的是引用对象的指针,也就是说不能改变指针的指向,但是对象内部可以改变。

1
2
3
4
5
6
7
8
const foo = {};

// 为 foo 添加一个属性,可以成功
foo.prop = 123;
foo.prop // 123

// 将 foo 指向另一个对象,就会报错
foo = {}; // TypeError: "foo" is read-only

特点和let一样