const 声明常量

172 阅读2分钟

1. 基本用法

const 声明一个只读的常量。一旦声明,常量的值就不能改变。

const 一旦声明常量,就必须立即初始化,只声明不赋值就会报错。

const 只在声明所在的块级作用域内有效。

const 命令声明的常量不会提升,存在暂时性死区,只能在声明后使用。

const 声明常量不可重复声明。

2. 本质

const 实际上保证的并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。

对于简单类型的数据(数值、字符串、布尔值)而言,值就保存在变量指向的内存地址中,因此等同于常量。

但对于复合类型的数据(主要是对象和数组)而言,变量指向的内存地址保存的只是一个指针,const 只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,这完全不能控制。

因此,将一个对象声明为常量时必须非常小心。

const foo = {}

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

// 将 foo 指向另一个对象,就会报错
foo = {}
// TypeError: "foo" is read-only
const a = []
a.push('hello')  // 可执行
a.length = 0  // 可执行
a = ['Dave']   // 报错

如果真的想将对象冻结,应该使用 Object.freeze 方法。

const foo = Object.freeze({})

// 常规模式时,下面一行不起作用
// 严格模式时,该行会报错
foo.prop = 123

除了将对象本身冻结,对象的属性也应该冻结。下面是一个将对象彻底冻结的函数。

var constantize = (obj) => {
  Object.freeze(obj)
  Object.keys(obj).forEach( (key, i) => {
    if (typeof obj[key] === 'object') {
      constantize(obj[key])
    }
  })
}

3. ES6 声明变量的 6 种方法

ES5 只有2种方法:var、function

ES6 有6种方法:var、function、let、const、import、class