object.preventextensions()仅禁止向对象自身添加新自有属性,不影响原型链、__proto__、prototype或继承行为,真正控制原型需冻结/封印原型对象或切断原型链。

Object.preventExtensions() 不能禁止追加新原型,它和原型链完全无关。
这个方法只作用于对象自身,限制的是“能否向该对象添加新的自有属性”,对原型、原型的原型、__proto__ 或 prototype 属性本身没有任何影响。
❌ 常见误解澄清
- “禁止追加新原型” —— 这不是
preventExtensions的能力范围 -
preventExtensions(obj)不会:- 阻止修改
obj.__proto__ - 阻止修改
obj.constructor.prototype - 阻止给原型对象(如
Array.prototype)添加方法 - 影响原型链查找行为(
obj.toString()依然能沿链向上找)
- 阻止修改
它只做一件事:
✅ 让 obj 变成不可扩展 → 后续 obj.newProp = value 失败(严格模式报错,非严格模式静默忽略)
? 原型链相关操作,preventExtensions 完全不干预
const obj = { a: 1 };
Object.preventExtensions(obj);
// ✅ 仍然可以改原型(虽然不推荐)
obj.__proto__ = { b: 2 };
// ✅ 仍然可以给原型加方法(比如污染 Array.prototype)
Array.prototype.sayHi = function() { return 'hi'; };
// ✅ obj 仍能继承并调用
[].sayHi(); // 'hi'
// ❌ 但不能再给 obj 自身加属性
obj.c = 3; // 静默失败 / 报错(取决于模式)
? 真正影响原型的操作有哪些?
| 操作 | 是否受 preventExtensions 影响 |
说明 |
|---|---|---|
obj.__proto__ = newProto |
否 | 修改原型指针不受限(除非该属性被设为不可写/不可配置) |
Object.setPrototypeOf(obj, newProto) |
否 | 同上,只要 __proto__ 属性可写即可 |
SomeConstructor.prototype.newMethod = ... |
否 | 给构造函数的 prototype 加属性,和 obj 无关 |
obj.hasOwnProperty('x') |
否 | 查找逻辑不变,只是自有属性不能再新增 |
⚠️ 注意:
__proto__本身是一个可配置、可写的访问器属性(在大多数引擎中),所以即使obj被preventExtensions,也不妨碍你动它的原型链接。
✅ 如果你真想“锁住原型链”,得换思路:
- 使用
Object.freeze(Object.getPrototypeOf(obj))冻结直接原型(仅一层,不递归) - 用
Object.seal()封装构造函数的prototype,防止意外添加方法 - 创建对象时用
Object.create(null)切断原型链(彻底无继承) - 在类定义中使用
static+private字段 + TypeScript 类型约束,从设计上规避原型滥用
不复杂但容易忽略:preventExtensions 是“封对象自身”,不是“封继承关系”。要控原型,得去管原型对象本身,或者用更底层的机制。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











