javascript原型链动态修改对已创建实例的影响取决于是否遮蔽、替换或冻结:未遮蔽时,增删改原型属性会立即生效;实例自有同名属性则断连原型;整体替换prototype后旧实例完全不受影响。

JavaScript 中原型链的动态修改,对已创建实例的影响取决于“改的是什么”以及“实例有没有自己定义同名属性”。它不是响应式更新,而是每次属性访问时实时查找的结果——改了就立刻可见,但前提是没被遮蔽、没被替换、也没被冻结。
改原型对象的内容,旧实例马上能用
只要没动 Person.prototype = {...} 这种整体赋值,而是在原有原型上增、删、改,比如:
-
Person.prototype.sayHi = function() { console.log('Hi'); };→ 所有已创建且没定义sayHi的实例,立刻可以调用 -
Person.prototype.age = 25;→ 没设置过age的实例,下次读person.age就是 25 -
delete Person.prototype.name;→ 实例再读name,会继续往上找(比如到Object.prototype),或返回undefined
这是因为所有实例的 __proto__ 都指向同一个原型对象,引擎每次访问都重新查,不缓存、不复制。
实例自己设了同名属性,就“断连”了原型
一旦实例写入同名属性,比如 person1.age = 30,后续所有对该属性的读写都只发生在实例自身:
-
person1.age始终是 30,哪怕你后来把Person.prototype.age改成 25 或删掉 -
person1.hasOwnProperty('age')返回true,说明遮蔽已发生 - 删除实例属性后:
delete person1.age,再读person1.age就又会回到原型上找
替换了整个 prototype,旧实例完全不受影响
用赋值方式重写原型,比如:
Person.prototype = { say() { } };这个操作只影响之后 new Person() 创建的新实例。旧实例的 __proto__ 仍指向原来的原型对象:
- 旧实例无法访问新原型上的
say方法 - 旧实例依然能读写原来原型上的属性(哪怕你后来又改了它)
-
oldInst instanceof Person可能变成false,因为instanceof查的是__proto__链是否包含当前Person.prototype
引用类型属性要特别当心共享问题
如果原型上定义的是对象或数组,比如:
Person.prototype.config = { timeout: 5000 };所有实例默认共享同一份内存:
-
person1.config.timeout = 3000→person2.config.timeout也会变成 3000 - 想隔离?在构造函数里初始化:
this.config = { timeout: 5000 }; - 安全做法是:原型上只放方法,状态类数据由实例自己管理
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











