详细讲解js中Object的preventExtensions、seal、freeze

63 阅读1分钟

在 JavaScript 中,Object.preventExtensionsObject.sealObject.freeze 是三个用于控制对象可变性的方法。它们都可以限制对象的行为,但限制的程度不同。


✅ 一句话区分(先给结论)

方法能否添加属性能否删除属性能否修改属性值能否修改属性描述符
preventExtensions
seal
freeze

1. Object.preventExtensions(obj)

✅ 作用:

禁止添加新属性,但可以删除、修改已有属性。

🔍 示例:

const obj = { a: 1 };
Object.preventExtensions(obj);

obj.b = 2; // 静默失败(非严格模式)
console.log(obj.b); // undefined

delete obj.a; // ✅ 可以删除
obj.a = 10; // ✅ 可以修改

🧪 检测:

Object.isExtensible(obj); // false

2. Object.seal(obj)

✅ 作用:

  • 禁止添加新属性
  • 禁止删除已有属性
  • 可以修改属性值

相当于 preventExtensions + 把所有属性设为 configurable: false

🔍 示例:

const obj = { a: 1, b: 2 };
Object.seal(obj);

obj.a = 10; // ✅ 可以改值
delete obj.a; // ❌ 删除失败
obj.c = 3; // ❌ 添加失败

🧪 检测:

Object.isSealed(obj); // true

3. Object.freeze(obj)

✅ 作用:

  • 禁止添加、删除、修改属性值
  • 禁止修改属性描述符(如 writableenumerableconfigurable

相当于 seal + 把所有属性设为 writable: false

🔍 示例:

const obj = { a: 1, b: { x: 10 } };
Object.freeze(obj);

obj.a = 100; // ❌ 修改失败
obj.c = 3; // ❌ 添加失败
delete obj.a; // ❌ 删除失败

⚠️ 注意:

freeze浅冻结,嵌套对象仍然可变:

obj.b.x = 999; // ✅ 可以改

🧪 检测:

Object.isFrozen(obj); // true

✅ 总结图(记忆版)

方法添加删除修改值修改描述符
preventExtensions
seal
freeze

✅ 实际应用建议

场景推荐方法
防止扩展结构preventExtensions
保护配置对象(如全局配置)seal
实现不可变对象(如 Redux state)freeze

如需深冻结(递归冻结嵌套对象),可手动实现:

function deepFreeze(obj) {
  Object.freeze(obj);
  for (const key in obj) {
    if (typeof obj[key] === 'object' && obj[key] !== null) {
      deepFreeze(obj[key]);
    }
  }
  return obj;
}