ECMAScript系列之const

85 阅读2分钟

常量

可变的叫做变量,不可变的叫做常量。在 ES6 推出之后可以使用 const 来声明常量。

ES5 中声明常量

大家现在都会用 const 来声明常量了,那你知道用 ES5 如何来声明常量吗?

没错,可以借助 Object.defineProperty()挂载一个变量名到 window,设置 writable 为 false 就可以实现

Object.defineProperty(window, 'PI', {
  value: 3.1415962,
  writable: false,
});
console.log(window.PI);
<!-- PI = 2; -->

cosnt 特性

  • 一旦声明,不可改变
  • 不存在变量提升
  • 不属于顶层对象 window
  • 具有暂时性死区
  • 不能重复声明
  • 块级作用域

一旦声明,不可改变

const 除了具有 let 的块级作用域和不会变量提升外,还有就是它定义的是常量,在用 const 定义变量后,我们就不能修改它了,对变量的修改会抛出异常。

const PI = 3.1415

console.log(PI)

PI = 5

console.log(PI)
// Uncaught TypeError: Assignment to constant variable.

这个代码块中因为对 PI 尝试修改,导致浏览器报错,这就说明 const 定义的变量是不能被修改的,它是只读的。聪明的同学一定会发现只读属性是不是一定要进行初始化呢?

const PI

PI = 3.1415
// Uncaught SyntaxError: Missing initializer in const declaration

const 声明的变量必须进行初始化,不然会抛出异常 Uncaught SyntaxError: Missing initializer in const declaration。

重点来喽

看代码片段

const obj = {
  name: 'admin',
  age: 18
}
obj.sex = 0
console.log(obj)
<!-- {name: 'admin', age: 18, sex: 0} -->

大家会发现 const 定义的 obj 竟然被改变了... 这到底是为什么呢?有点懵啊...

这时我们就需要了解 JS 中的变量是如何存储的,见下图:

图片

基本数据类型存储在 栈内存 中,引用数据类型存储在 堆内存 中然后在栈内存中保存 引用地址 。

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

如何让对象或者数组这种引用数据类型也不被改变呢?

Object.freeze(obj)

Object.freeze() 只是浅层冻结,只会对最近一层的对象进行冻结,并不会对深层对象冻结。