object.seal允许修改已有属性值但禁止增删属性和改描述符,object.freeze彻底禁止修改属性值、增删属性及改描述符,且禁止修改原型;二者均为浅冻结,嵌套对象不受影响。

Object.seal 和 Object.freeze 都是用来限制对象修改的内置方法,但它们的“防护等级”不同:seal 是“结构锁定”,freeze 是“全盘冻结”。选哪个,关键看你要阻止哪些操作。
能不能改属性值?这是最直接的分水岭
这是两者最直观的区别。seal 允许修改已有属性的值(只要该属性 writable 为 true),freeze 则彻底禁止。
- seal 后:obj.name = "Tom" ✅ 有效;obj.age = 35 ✅ 有效
- freeze 后:obj.name = "Tom" ❌ 静默失败(非严格模式)或报错(严格模式);obj.age = 35 同样无效
能不能删或加属性?两者都禁止
无论是 seal 还是 freeze,对象自身的属性集合就固定了——不能新增,也不能删除。
- obj.city = "Shanghai" → 两者都会被忽略(非严格模式)或抛 TypeError(严格模式)
- delete obj.age → 两者都返回 false,且属性依然存在
能不能改属性描述符?比如 writable、configurable?
两者都不允许重新配置属性。调用 Object.defineProperty 修改任何自有属性的 descriptor,都会失败。
- Object.defineProperty(obj, 'name', { writable: false }) → seal 或 freeze 后均报错
- seal 会把所有自有属性的 configurable 设为 false;freeze 在此基础上,还把所有自有属性的 writable 也设为 false
嵌套对象和原型链不受影响
这两个方法都是浅层操作,只作用于对象自身,不递归处理子对象,也不阻断原型链变更(除了 freeze 明确禁止修改原型)。
- const data = { user: { name: "Alice" } }; Object.freeze(data); data.user.name = "Bob" ✅ 仍可改(因为 user 对象没被 freeze)
- Object.setPrototypeOf(obj, newProto) → seal 允许;freeze 禁止
- 如需深层冻结,得手动递归调用 Object.freeze,或借助工具函数处理循环引用











