防止一些共享代码或者 JavaScript 库被人有意无意的修改了核心代码等。
1. 不可扩展的对象 Object.preventExtensions()
let obj = {name:"k&k"};
Object.preventExtensions(obj);
obj.name // "k&k"
obj.age = 2;
obj.age // undefined
obj.name = "hello";
obj.name // "hello"
调用 Object.preventExtensions() 方法后,就不能再 obj 对象添加属性和方法了,非严格模式下,添加的属性或方法默认失败,显示 undefined,严格模式下报错。但给已有的成员可以修改或删除。
Object.isExtensible()
可以用来检测对象是否可以扩展。可扩展返回 true,不可扩展返回 false
Object.isExtensible(obj); // false
let o = {};
Object.isExtensible(o); // true
2.密封的对象 Object.seal()
对于密封的对象。不可扩展,而且已存在成员的 [[Configurable]] 特性被设置为 false。意味着不能进行删除。因为不能使用 Object.defineProperty() 把数据属性修改为访问器属性,或者相反。但 属性值是可以修改的。非严格模式下会忽略,严格模式下回报错。
let obj = {name:"kk"}
Object.seal(obj);
obj.name; // "kk"
delete obj.name; // false
obj.name; // "kk"
obj.age = 2;
obj.age; // undefined
obj.name = "hello";
obj.name; //"hello"
Object.isSealed()
用来检测对象是否被密封,密封对象返回 true,未密封对象返货 false。因为被密封的对象不可扩展,所以用 Object.isExtensible() 检测也会返回 false。
Object.isSealed(obj) // true
Object.isExtensible(obj) // false
3.冻结对象 Object.freeze()
最严格的防篡改就是冻结对象。被冻结的对象,既不可扩展也是密封的,而且对象属性的 [[Writable]] 特性会被设置为 false。如果定义 [[Set]] 函数,访问器属性仍然是可写的。
let obj = {name: "kk"};
Object.freeze(obj);
obj.age = 29;
obj.age // undefined
delete obj.name // false
obj.name // "kk"
obj.name = "hello"
obj.name // "kk"
冻结和密封与不可扩展一样,非严格模式下回忽略,严格模式下会报错。
Object.isFrozen()
检测对象是否被冻结。因为冻结对象既是密封的又是不可扩展的,所以用 Object.isSealed() 和 Object.isExtensbile() 会分别返回 true 和 false。
Object.isFrozen(obj); // true
Object.isSealed(obj) // true
Object.isExtensible(obj) // false