掌握 JavaScript 中的 Object.freeze() 和 Object.seal():控制对象可变性
JavaScript 中的 Object.freeze 和 Object.seal
在 JavaScript 中使用对象时,控制其可变性对于防止意外更改至关重要。JavaScript 为此提供的两种方法是 **Object.freeze()** 和 **Object.seal()**。了解它们的区别和用例是编写健壮代码的关键。
1. Object.freeze()
`Object.freeze()` 方法使对象**不可变**。这意味着:
句法:
Object.freeze(obj);
例子:
const obj = { name: "Alice", age: 25 }; Object.freeze(obj); obj.age = 30; // Does nothing (strict mode: throws an error) obj.gender = "female"; // Does nothing (strict mode: throws an error) delete obj.name; // Does nothing (strict mode: throws an error) console.log(obj); // { name: "Alice", age: 25 }
用例:
检查物体是否被冻结:
使用 `Object.isFrozen()` 来判断一个对象是否被冻结:
console.log(Object.isFrozen(obj)); // true
2. 对象.seal()
`Object.seal()` 方法限制对对象的修改,但不如 `Object.freeze()` 严格。它允许:
句法:
Object.seal(obj);
例子:
const obj = { name: "Bob", age: 30 }; Object.seal(obj); obj.age = 35; // Allowed: Existing properties can be modified obj.gender = "male"; // Does nothing (strict mode: throws an error) delete obj.name; // Does nothing (strict mode: throws an error) console.log(obj); // { name: "Bob", age: 35 }
用例:
检查对象是否被密封:
使用 `Object.isSealed()` 来判断一个对象是否被密封:
console.log(Object.isSealed(obj)); // true
3. Object.freeze() 和 Object.seal() 之间的主要区别
4. 冷冻和密封的嵌套对象
`Object.freeze()` 和 `Object.seal()` 都是 **浅** 的,这意味着它们不会影响嵌套对象。要深度冻结或密封对象,您需要将该方法递归应用于每个嵌套对象。
示例(浅层效应):
const obj = { name: "Eve", details: { age: 28 } }; Object.freeze(obj); obj.details.age = 30; // Allowed, as `details` is not frozen console.log(obj); // { name: "Eve", details: { age: 30 } }
Deep Freeze 助手功能:
function deepFreeze(obj) { Object.freeze(obj); for (const key in obj) { if (typeof obj[key] === "object" && obj[key] !== null) { deepFreeze(obj[key]); } } } const obj = { name: "Eve", details: { age: 28 } }; deepFreeze(obj); obj.details.age = 30; // Not allowed console.log(obj); // { name: "Eve", details: { age: 28 } }
5. 常见陷阱和提示
结论
`Object.freeze()` 和 `Object.seal()` 都是用于管理 JavaScript 中对象不变性的有用工具。虽然 `Object.freeze()` 确保完全不变,但 `Object.seal()` 通过允许更改现有属性值提供了灵活性。选择正确的方法取决于您对对象的控制级别。