ES6 let和const命令

97 阅读2分钟

let和const命令

暂时性死区(temporal dead zone,简称 TDZ)

在代码块内,使用let命令声明变量之前,该变量都是不可用的。

var temp = 10
if (true) {
    temp = 'abc';
    let temp // ReferenceError
}

let和var的区别:

  1. let声明的变量只在它所在的代码块有效。
{
    let a = 10
    var b = 1
}
a // ReferenceError: a is not defined.
b // 1
  1. let声明的变量不会发生“变量提升”,变量必须在声明后才能使用。
console.log(a) // undefined
var a = 10

console.log(b) // 报错ReferenceError
let b = 10

var声明变量a前,它就已经存在,但没有值;let未声明变量b前,它不存在。

  1. let不允许在相同作用域内,重复声明同一个变量.
function func(arg) {
    let arg
}
func() // 报错

function func(arg) {
    {
        let arg
    }
}
func() // 不报错

const和var的区别:

  1. const声明一个只读的常量:声明后常量的值不能改变;声明必须赋值。
const PI = 3.1415
PI // 3.1415
PI = 3 // TypeError: Assignment to constant variable.

const b;
// SyntaxError: Missing initializer in const declaration
  1. const声明的变量只在声明所在的块级作用域内有效。
if (true){
    const MAX = 5
}
MAX // Uncaught ReferenceError: MAX is not defined
  1. const声明的变量不会发生“变量提升”,同样存在暂时性死区,只能在声明后的位置使用。
if (true){
    console.log(MAX) // ReferenceError
    const MAX = 5
}
  1. const不可重复声明
var mes = 'Hello'
let age = 20

const mes = 'bye' // 报错
const age = 30 // 报错

const实质

const保证变量指向的内存地址所保存的数据不能改变,对于简单类型数据,值保存在变量指向的内存地址;对于复杂类型的数据,变量指向的内存地址,保存的是一个指向实际数据的指针,const只能保证指针是固定的(始终指向另一个固定的地址)。

// foo存放的是一个地址,这个地址指向一个对象;地址不可变,对象本身可变
const foo = {}
foo.prop = 123; // 可以为foo添加属性
console.log(foo.prop) // 123

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

如果要冻结对象,可以使用Object.freeze方法

const foo = Object.freeze({})