Object.preventExtensions()仅阻止添加新属性,不影响已有属性的读写、配置、枚举及删除;调用后不可逆,可用Object.isExtensible()检测;约束力弱于seal和freeze。

Object.preventExtensions() 用于阻止向对象添加新属性,但已存在的属性仍可读写、可配置、可枚举,也不能改变其属性描述符(如把 data 属性改成 accessor)。
核心效果:只封“新增”,不锁“已有”
调用后,对象进入“不可扩展”状态:
- 无法通过点号(
obj.newProp = 1)、方括号(obj['newProp'] = 1)或Object.defineProperty()添加新属性; - 已存在属性的值、可写性(
writable)、可配置性(configurable)、可枚举性(enumerable)完全不受影响; - 可以删除已有属性(
delete obj.existing),也可以修改其值或属性描述符(只要configurable: true); - 该操作是单向的——无法撤销,也无法恢复为可扩展状态。
如何检测对象是否被禁止扩展
使用 Object.isExtensible(obj) 判断:
- 返回
true表示对象仍可扩展; - 返回
false表示已被preventExtensions(或更严格的seal/freeze)处理过。
注意:isExtensible 是唯一能直接区分“未处理”和“已 preventExtensions”的方法;isSealed 和 isFrozen 在 preventExtensions 后仍返回 false(除非进一步调用 seal 或 freeze)。
立即学习“Java免费学习笔记(深入)”;
与 Object.seal()、Object.freeze() 的区别
三者是递进关系,约束力度逐级增强:
-
preventExtensions:只禁新增属性; -
seal=preventExtensions+ 所有现有属性configurable: false(不能删、不能改描述符); -
freeze=seal+ 所有现有数据属性writable: false(值不可改)。
例如:Object.preventExtensions({ a: 1 }) 后,仍可执行 obj.a = 2、delete obj.a、Object.defineProperty(obj, 'a', { value: 3 })(因 a 原本 configurable)。
实际使用建议
适合在对象结构基本稳定、仅需防止误加字段时使用,比如配置对象、常量容器或 API 返回的只读结构体:
- 避免在运行中动态拼接属性名导致意外覆盖或污染;
- 配合
Object.defineProperty预设属性时,提前调用更安全; - 不要依赖它实现“真正只读”——需用
freeze或代理(Proxy)做深层防护; - 对数组调用时,禁止新增索引属性(如
arr[100] = x),但push、length修改等仍有效(因其本质是修改已有属性length并触发内部逻辑)。


















