object.preventextensions()仅限制目标对象自身扩展,不影响原型对象及其新增属性的继承。需单独对原型调用preventextensions/seal/freeze才能锁定原型行为。

不能直接用 Object.preventExtensions() 防止“原型对象被扩展”来影响实例的行为,因为该方法只冻结**目标对象自身**的可扩展性,对它的原型链没有约束力。也就是说,它不会阻止原型对象新增属性,也不会阻止实例从原型继承新添加的属性。
Object.preventExtensions() 的作用范围有限
这个方法仅让传入的对象(比如某个具体对象)不能再添加新属性,但不改变其原型对象,也不切断原型链:
- 它只锁定目标对象自身的属性添加行为(
obj.newProp = 1会静默失败或抛错,取决于严格模式) - 原型对象本身是否可扩展,完全不受影响——你仍可对
obj.__proto__或构造函数的prototype做增删改 - 如果原型后来新增了属性或方法,已存在的实例依然能通过原型链访问到(因为原型链查找机制没被破坏)
常见误解:以为锁住实例就能锁住原型
例如:
function Person() {}
Person.prototype.sayHi = function() { return 'hi'; };
const p = new Person();
Object.preventExtensions(p); // 只锁 p 自身
// ✅ 以下操作仍然成功:原型未被锁定
Person.prototype.sayBye = function() { return 'bye'; };
console.log(p.sayBye()); // 'bye' —— 实例仍能访问新添加的原型方法
真正想“防止原型被扩展”,得单独处理原型对象
如果你希望某个构造函数的原型不可再添加属性,必须显式地对那个原型对象调用 preventExtensions(或更严格的 seal/freeze):
-
锁定原型本身:
Object.preventExtensions(Person.prototype) -
彻底封印(推荐):
Object.seal(Person.prototype)(禁止增删 + 设置为不可配置) -
完全冻结:
Object.freeze(Person.prototype)(还禁止修改现有属性值)
注意:这些操作需在原型被广泛使用前完成;一旦其他代码已给原型添加了属性,再 seal/freeze 就只能保护后续变更,不影响已有内容。
补充:实例与原型的扩展性是独立的
一个对象的可扩展性与其原型的可扩展性无关:
- 实例可扩展,原型也可扩展 —— 默认情况
- 实例被
preventExtensions,原型仍可自由扩展 - 原型被
seal,实例仍可自由添加自身属性(除非实例也被单独锁定)
二者互不干扰,必须分别控制。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











