JS一千问(13):防止修改对象的方法有哪些?

有多种方法可以根据需要锁定对象。

  1. Object.freeze()
  2. Object.seal()
  3. Object.preventExtensions()

Object.freeze()

对象属性:不可添加 | 不可删除 | 不可修改。

冻结对象不允许将新属性添加到对象并阻止删除或更改现有属性,任何修改对象的尝试都会失败,静默或抛出TypeError异常(在严格模式下最常见,但不是唯一的)。

var role = { name: "koala", lv: 9 };
Object.freeze(role);

role.coin = 2;  // 严格模式下会抛出错误
console.log(role.coin);  // undefined

delete role.lv;  
console.log(role.lv); // 9

role.name = "tom";
console.log(role.name); // koala

冻结对象对于表示逻辑上不可变的数据结构非常有用,尤其是在更改对象的属性可能导致应用程序其他地方出现不良行为的情况下。

Object.freeze()是浅冻结,属性对象值仍然是可改变的,如:

var role = { name: "koala", lv: {a:1} };
Object.freeze(role);

role.lv.a = 2;
console.log(role.lv.a); // 2

如此,要使对象完全不可变,需要递归处理挂载的所有对象类型的属性,即深冻结。参考:

function deepFreeze(obj) {
	var propNames = Object.getOwnPropertyNames(obj);
	propNames.forEach(function(name) {
		var prop = obj[name];
		if (typeof prop == 'object' && prop !== null) deepFreeze(prop);
	});

	return Object.freeze(obj);
}

obj2 = { attr: {} };

deepFreeze(obj2);
obj2.attr.a = 'hello';
obj2.attr.a; // undefined

Object.seal()

对象属性:不可添加 | 不可删除 | 可修改。

Object.seal()在功能上是Object.preventExtensions的超集,因为它在防止将任意属性附加到对象的同时,也防止修改已有属性的可枚举性、可配置性、可写性。此外,它不允许删除属性。

var role = { name: "koala", lv: 9 };
Object.seal(role);

role.coin = 2;  // 严格模式下会抛出错误
console.log(role.coin);  // undefined

delete role.lv;  
console.log(role.lv); // 9

role.name = "tom";
console.log(role.name); // tom

Object.preventExtensions()

对象属性:不可添加 | 可删除 | 可修改。

Object.preventExtensions() 将对象的可扩展属性设置为false,以便不能向其添加新属性。这是一个永久性的改变:一旦一个对象被设置为不可扩展,它就不能再被设置为可扩展。

var role = { name: "koala", lv: 9 };
Object.preventExtensions(role);

console.log(Object.isExtensible(role)); // false

role.coin = 2;  // 严格模式下会抛出错误
console.log(role.coin);  // undefined

delete role.lv;  
console.log(role.lv); // undefined

role.name = "tom";
console.log(role.name); // tom

Leave a Comment

您的电子邮箱地址不会被公开。 必填项已用*标注