ES6的let与const

es6虽然才正式发布几个月,但是到了我找工作的时候估计就是必备的基础知识了,再不学,估计到时候就要被淘汰了。

let

es6之前都是没有块级作用域的,虽然大家都把这个毛病当作JavaScript的特性来看,但是es6添加了块级作用域的概念:

for(var i=0;i<=10;i++){
    ...    
}
console.log(i);  //10

我们无意间就定义了一个全局变量,这与我们的原意不符合,于是有了let命令之后,这种情况就不会出现了:

for(let i=0;i<=10;i++){
    ...
}
console.log(i) //undefined

没有变量提升

再var指令定义变量的时候,会存在变量提升的情况,但是let不会,所以一定要先声明,再使用:

console.log(foo); // 输出undefined
console.log(bar); // 报错ReferenceError

var foo = 2;
let bar = 2;

暂时性死区

当使用let命令时,它所声明的变量就不会收到外部的影响,即便是在声明之前使用的:

var tmp = 123;

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

而在let声明之前的变量,都会发生错误,这就是暂时性死区。

if (true) {
  // TDZ开始
  tmp = 'abc'; // ReferenceError
  console.log(tmp); // ReferenceError

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

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

以前没有声明的变量 用typeof方法会返回undefined,
但是如果现在这样:

typeof x; // ReferenceError
let x;

因为生成了暂时性死区,就会发生错误了。

不可重复声明

与var不同,let命令不可以重复声明。

function () {
  let a = 10;
  var a = 1;
}

// 报错
function () {
  let a = 10;
  let a = 1;
}

const

const声明一个只读变量,声明之后不可以改变:

const PI = 3.1415;
PI // 3.1415

PI = 3;
// TypeError: Assignment to constant variable.

那么你在用const声明变量的同时就得为变量赋值,不要等到以后再赋值。
同样的情况,用const声明也不存在变量的提升,不可以重复声明,而且会存在暂时性死区。

但是const声明变量再存储一个地址的时候,它所对应的对象值是可以有所改变的:

const a = [];
a.push('Hello'); // 可执行
a.length = 0;    // 可执行
a = ['Dave'];    // 报错

但不可以重新赋值,要保证存储的地址是不变的。

而且,用let与const声明的变量,不会成为window对象的属性。

var a = 1;
window.a // 1

let b = 1;
window.b // undefined