Object.preventExtensions仅禁止添加新属性,允许修改已有属性值、删除属性及更改属性描述符;严格模式下新增属性抛TypeError,非严格模式下静默失败;可用Object.isExtensible检测。

Object.preventExtensions 会阻止哪些操作
Object.preventExtensions 只冻结对象的「扩展性」,即禁止添加新属性(包括自有属性和通过原型链继承的属性),但不阻止修改已有属性值、删除属性或重写属性描述符(如 writable、configurable)。
常见误解是它等同于「只读」或「冻结」,其实不是——Object.freeze 和 Object.seal 才有更强限制。
- ✅ 允许:
obj.existing = "new value"、delete obj.existing、Object.defineProperty(obj, "existing", {...}) - ❌ 禁止:
obj.newProp = 1、obj["newProp"] = 1、Object.defineProperty(obj, "newProp", {...})
在严格模式下新增属性会直接报错
非严格模式下,向被 Object.preventExtensions 处理过的对象添加新属性只是静默失败;严格模式下则抛出 TypeError: Cannot add property newProp, object is not extensible。
这意味着:如果你依赖报错来捕获非法写入,必须确保代码运行在严格模式("use strict")下,否则可能掩盖问题。
- 严格模式触发错误:
"use strict"; const o = {}; Object.preventExtensions(o); o.x = 1;→ 报错 - 非严格模式无提示:
const o = {}; Object.preventExtensions(o); o.x = 1;→o.x仍为undefined,赋值无效但不提醒
如何检测一个对象是否已被防止扩展
用 Object.isExtensible 判断最可靠,返回 false 表示不能再添加新属性。
注意:不能靠 in 操作符、hasOwnProperty 或遍历 keys 来反推——它们只反映当前属性存在与否,跟是否可扩展无关。
- 正确检测:
Object.isExtensible(obj) === false - 错误假设:
Object.keys(obj).length === 0或!("prop" in obj)都无法说明是否被防止扩展 - 兼容性:所有现代引擎和 IE9+ 均支持
Object.isExtensible
与 Object.seal / Object.freeze 的关键区别
三者都是防篡改手段,但作用层级不同。混淆使用会导致预期外行为,比如误以为 preventExtensions 能阻止属性删除或修改。
-
Object.preventExtensions:仅禁新增(最轻量) -
Object.seal=preventExtensions+ 所有现有属性configurable: false(禁删、禁重定义,但可改值) -
Object.freeze=seal+ 所有现有属性writable: false(完全只读)
性能上,preventExtensions 开销最小;若只需控制新增入口(例如配置对象初始化后封口),它比 freeze 更合适——后者还会递归冻结嵌套对象(如果手动实现),而 preventExtensions 不影响嵌套对象本身。

















