可以通过Object对象的一些方法控制对象属性的操作权限,Javasctipt控制对象的有三种,分别是扩展、密封、冻结。
防止扩展,不可增加新的属性
密封,不可增加新的属性,不可删除属性或修改属性的特性,但是值仍然可以被修改(writable为true))
冻结,不可增加新的属性,不可删除和修改属性的特殊,不可修改值
Object.preventExtensions 函数
让一个对象变为不可扩展,也就是永远不能再添加新的属性。
Object.preventExtensions(obj)
如果一个对象可以添加新的属性,则这个对象是可扩展的。Object.preventExtensions()将对象标记为不再可扩展后,它将永远不会接受新添加的属性。
判断一个对象是否可以扩展使用 Object.isExtensible
方法,返回true或false
// Object.preventExtensions 返回传递给函数的对象(被变为不可扩展)
var obj = {};
var obj2 = Object.preventExtensions(obj);
obj === obj2; // true
// 对象默认都是可扩展的
var empty = {};
Object.isExtensible(empty); // === true
Object.preventExtensions(empty);
Object.isExtensible(empty); // === false
var nonExtensible = { removable: true };
Object.preventExtensions(nonExtensible);
Object.defineProperty(nonExtensible, 'new', {
value: 8675309
}); // 报错
// 在严格模式下,给不可扩展的对象添加新属性,报错
function fail() {
'use strict';
// 报错
nonExtensible.newProperty = 'FAIL';
}
fail();
var obj = new Object();
Object.preventExtensions(obj);
obj.p = 1;
obj.p // undefined
上面代码如果在严格模式下('use strict'
),会报错
如果对象 obj
是不可扩展的,用 Object.definePropert
添加新属性都会报错
Object.seal 函数
使一个对象密封,并返回被密封后的对象。密封对象将会阻止向对象添加新的属性,并且会将所有已有属性的可配置性(configurable)置为不可配置(false),即不可修改属性的描述或删除属性。但是可写性描述(writable)为可写(true)的属性的值仍然可以被修改。
Object.seal实质是把属性描述对象的configurable属性设为false,因此属性描述对象不再能改变了。
判断一个属性是不是密封状态用Object.isSealed()
函数
var obj = {
p: 'a'
};
// seal方法之前
Object.getOwnPropertyDescriptor(obj, 'p')
// Object {
// value: "a",
// writable: true,
// enumerable: true,
// configurable: true
// }
Object.seal(obj);
// seal方法之后
Object.getOwnPropertyDescriptor(obj, 'p')
// Object {
// value: "a",
// writable: true,
// enumerable: true,
// configurable: false
// }
Object.defineProperty(o, 'p', {
enumerable: false
})
// TypeError: Cannot redefine property: p
Object.seal只是禁止新增或删除属性,并不影响修改某个属性的值。
Object.freeze 函数
可以冻结一个对象,冻结指的是不能向这个对象添加新的属性,不能修改其已有属性的值,不能删除已有属性,以及不能修改该对象已有属性的可枚举性、可配置性、可写性。也就是说,这个对象永远是不可变的。该方法返回被冻结的对象。
var obj = {
p: 'hello'
};
Object.freeze(obj);
obj.p = 'world';
obj.p // "hello"
obj.t = 'hello';
obj.t // undefined
delete obj.p // false
obj.p // "hello"
对obj对象进行Object.freeze()以后,修改属性、新增属性、删除属性都无效了。这些操作并不报错,只是默默地失败。如果在严格模式下,则会报错
判断一个对象是不是冻结状态用Object.isFrozen()
函数