对象密封限制新增属性、删除属性和重新配置属性,但允许修改已有可写属性的值;它比不可扩展多禁删除,比冻结少禁改值,适用于结构稳定而内容需可变的场景。

JavaScript 中的 对象密封(sealing) 主要是为了在不冻结对象的前提下,防止意外修改对象的结构——也就是禁止新增或删除属性,同时保留对已有属性值的修改能力。
密封对象限制哪些操作?
调用 Object.seal(obj) 后,对象会进入“密封”状态,以下操作会被阻止:
- 不能添加新属性(
obj.newProp = 1无效,严格模式下抛出错误) - 不能删除已有属性(
delete obj.existingProp失败,严格模式下报错) - 不能重新配置属性(即不能改
configurable: false,所以也不能再用Object.defineProperty改 descriptor 中的configurable或writable)
但注意:已存在的可写属性(writable: true)的值仍可修改,比如 obj.name = "Alice" 是允许的。
和冻结(freeze)、不可扩展(preventExtensions)的区别
三者是递进关系,限制力度逐步增强:
立即学习“Java免费学习笔记(深入)”;
-
不可扩展(
Object.preventExtensions()):只禁新增,允许删、允许改值、允许改 descriptor -
密封(
Object.seal()):禁新增 + 禁删除,但仍允许改已有属性的值(只要 writable) -
冻结(
Object.freeze()):禁新增 + 禁删除 + 禁改值(所有属性设为writable: false),是最严格的保护
为什么需要密封?实用场景有哪些?
密封适合那些“结构应稳定、但内容可变”的对象,比如配置项、常量集合、模块导出对象:
- 防止其他代码误删关键字段(如
config.baseUrl被删导致运行时错误) - 避免污染全局配置对象,同时又不必完全禁止值更新(比如运行时切换调试开关)
- 作为开发期防御手段,在测试或沙箱环境中加固对象边界
它比 freeze 更灵活,比默认对象更安全,是一种轻量级的结构防护。
基本上就这些——密封不是为了彻底锁死,而是守住“形状”,放开“内容”。











