Object.seal 阻止添加新属性、禁止删除和重配置现有属性,但允许修改可写属性的值;与 Object.freeze 的区别在于不改变 writable 状态。

Object.seal 会阻止向对象添加新属性,同时将所有现有属性设为不可配置(即不能删除、不能改描述符),但允许修改已有属性的值(前提是该属性本身是可写的)。
密封对象的核心效果
调用 Object.seal(obj) 后:
- 无法添加新属性(
obj.newProp = 1失败,严格模式下报错,非严格模式静默忽略) - 无法删除已有属性(
delete obj.existingProp返回false) - 无法更改属性的描述符(如把
writable改为false,或把configurable改为true) - 已有属性的值仍可修改(只要其
writable: true)
和 Object.freeze 的区别
二者都禁止添加/删除属性、锁定配置,但关键差异在可写性:
-
Object.seal:不改变属性的
writable状态;原来可写的仍可写 -
Object.freeze:还会把所有属性的
writable设为false,彻底禁止赋值
例如:const obj = { a: 1 };<br>
Object.seal(obj);<br>
obj.a = 2; // ✅ 成功<br>
obj.b = 3; // ❌ 失败(无新属性)<br>
delete obj.a; // ❌ 失败(不可删除)<br>
Object.defineProperty(obj, 'a', { writable: false }); // ❌ 报错(不可重配置)
检查对象是否被密封
没有直接 API 判断是否密封,但可通过组合检测近似判断:
- 用 Object.isSealed(obj) —— 这是标准方法,返回布尔值
- 它内部检查:是否可扩展为
false,且每个自有属性的configurable都为false - 注意:
Object.isSealed({})返回true(空对象默认可扩展,但未 seal 前不是 sealed)
实际使用建议
密封适合「结构定型、只读配置但允许运行时更新值」的场景,比如:
- 模块导出的配置对象,希望防止误加字段或删键,但允许业务逻辑动态更新某些字段
- 构造函数中初始化实例后,立即 seal 防止外部篡改结构
- 搭配
Object.preventExtensions或Object.freeze分层控制(先 preventExtensions,再 seal,最后 freeze)










