ES6 - let 和 const

729 阅读3分钟

总结

let

let :在块级作用域有效,在该块级作用域之外将不能被访问。

let :不存在变量提升(变量提升即将变量声明提升到它所在作用域的最开始的部分)。

let :声明的变量不能重复声明,不然会报错。

es6强制开始了严格模式,变量未声明不能使用,否则就会直接报错。

const

const :声明常量,在程序运行中不能直接被修改,不然会报错。

const :声明的时候一定要赋值,不然会报错。

const :在块级作用域有效,在该块级作用域之外将不能被访问。

const :如果声明了一个常量为json对象类型,那么这个常量里面的对象属性可以更改和添加

详解

1、不存在变量提升

var命令会发生“变量提升”现象,即变量可以在声明之前使用,值为undefined。

// var 的情况
console.log(foo); // 输出undefined
var foo = 2;

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

2、暂时性死区

只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)

let tmp = 123;
//代码块中的tmp将不受外部的tmp影响,形成TDZ
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不允许在相同作用域内,重复声明同一个变量。

//不会报错(外面的a和{}里的a不在同一作用域里)
let a = 18; 
if(true) {
  let a = 20;
}

//会报错(在同一作用域{}内)
if(true) {
  let a = 18;
  let a = 20;
}

4、不可改变的const命令,而且必须初始化

const 声明一个只读的常量。一旦声明,常量的值就不会改变。这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值。

const PI = 3.1415;
console.log(PI);  //3.1415
PI = 3.14;      //TypeError: Assignment to constant variable.

注: const命令跟let命令一样不存在变量提升、具有块级作用域、存在暂时性死区、不允许重复声明。

补充:为什么需要块级作用域?

场景一,内层变量可能会覆盖外层变量

var tmp = new Date();

function f() {
  console.log(tmp);
  if (false) {
    var tmp = 'hello world';
  }
}

f(); // undefined

上面代码的原意是,if代码块的外部使用外层的tmp变量,内部使用内层的tmp变量。但是,函数f执行后,输出结果为undefined,原因在于变量提升,导致内层的tmp变量覆盖了外层的tmp变量。

第二种场景,用来计数的循环变量泄露为全局变量。

var s = 'hello';

for (var i = 0; i < s.length; i++) {
  console.log(s[i]);
}

console.log(i); // 5

上面代码中,变量i只用来控制循环,但是循环结束后,它并没有消失,泄露成了全局变量。