我们知道,ES6引入的const是用来定义常量的,对于基本数据类型来说,变量存储的是数据的值,所以用起来没问题,但当我们使用const定义一个数组或者对象时,由于存储的是对象的地址,所以即使我们修改了对象的某一键值,或者为数组增加、删除一项,它的存储地址,所以依旧是常量,这有时候不是我们想要的。
那么要如何定义一个“真正”的对象类型的常量呢?
使用对象的属性描述符
使用configurable: false和writable: false创建一个常量属性(不可修改、重定义或删除)
var myObj = {};
Object.defineProperty(myObj, 'a', {
value: 1,
configurable: false,
writable: false
})
禁止扩展
禁止一个对象添加新的属性。原有的属性可以修改可以使用delete删除。
var myObj = {a: 2};
Object.preventExtensions(myObj);
myObj.b = 3;
myObj.b; // undefined
myObj.a = 3;
myObj.a; // 3
delete myObj.a // true
密封
Object.seal:创建一个“密封”的对象,实际上是在现有的对象上调用Object.preventExtensions(..)并把所有的现有属性标记为configurable: false
密封之后,不能添加新属性,也不能重新配置或删除任何现有属性,但是可以修改现有属性的值。
var obj = { a: 2 };
Object.seal(obj);
obj.b = 1;
obj.b // undefined
Object.defineProperty(obj, 'a', {
configurable: true
}) // Uncaught TypeError: Cannot redefine property: a
obj.a = 3
obj.a // 3
冻结
Object.freeze(..)创建一个冻结对象,实际上是在现有的对象上调用Object.seal(..)并把所有的“数据访问”属性标记为writable: false,这样就无法修改属性的值。这个方法是级别最高的不可变性。
Object.freeze(obj)
obj.a = 4
obj.a // 3