JavaScript Object对象方法之 freeze() seal() preventExtensions()

341 1 年前
有时需要控制对象的读写状态,防止对象被改变。JavaScript 提供了三种冻结方法,最弱的一种是Object.preventExtensions,其次是Object.seal,最强的是Object.freeze。

可以通过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()函数

分类栏目
© 2018邮箱:11407215#qq.comGitHub沪ICP备12039518号-6