常量
可变的叫做变量,不可变的叫做常量。在 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() 只是浅层冻结,只会对最近一层的对象进行冻结,并不会对深层对象冻结。