深入理解ES6之var、let、const

104 阅读2分钟

变量提升

在函数作用域或全局作用域中通过关键字var声明的变量,都会被当成在当前作用域顶部声明的变量。这就是提升机制。

其实在预编译阶段,JavaScript引擎将会把

var value = 6;

提升为

var value;
value = 6;

let块级声明

块级作用域存在于:

  • 函数内部
  • 块中({}之间)

let 禁止重复声明

在同一作用域中不能用let重复定义已经存在了的标识符。

const

const声明的常量如果是对象,可以修改对象内部的值。也就是不能修改const值的地址,但可以修改地址对象里面的值。

临时死区(Temporal Dead Zone)

JavaScript引擎在扫描代码变量声明时(预编译阶段),要么将他们提升至作用域顶部(var),要么将声明放在临时性死区中(TDZ),下面个两段代码很明确临时死区的存在。

console.log(typeof value) // 会在全局找value,未定义所以为'undefined'
if (condition) {
    let value = 'blue'
}
if (condition) {
   console.log(typeof value) // Cannot access 'value' before initialization 引用错误 
   let value = 'blue'  // 已经定义,但是在TDZ里面
}

循环中的let声明

之前使用var的时候:

var funs = [];
for( var i = 0; i < 10; i++) {
  funcs.push(function(value) {
    return function() {
      console.log(value)
    }
  }(i)); // 闭包
}
funcs.forEach(function(func) {
  func(); // 输出0、1、2··· 9
})

现在:


var funs = [];
for( let i = 0; i < 10; i++) {
  funcs.push(function(value) {
    console.log(value)
  }
}
funcs.forEach(function(func) {
  func(); // 输出0、1、2··· 9
})

let声明在循环内部的行为标准是 专门定义 的,他不一定与let的不提升特性相关!!!

事实上,早期的let实现并不包含这一行为,是后来加入的。

块级绑定的推荐使用

默认使用const,只有确实需要改变变量的值时使用let

因为大部分声明的值在初始化后不应再改变,而预料外的变量值的改变时很多bug的来源。