修改 prototype 属性本身不会影响已有实例,真正影响的是对原型对象内容的增删改;因实例共享原型引用,属性访问为实时查找,仅当实例自身遮蔽或原型被替换时才失效。

修改 prototype 属性本身**并不会**影响所有已创建的实例——这个说法是常见误解。真正影响已有实例的,是**对原型对象本身的修改**(比如增、改、删属性),而不是“修改构造函数的 prototype 属性”这一动作。
关键区分:改原型对象 vs 改 prototype 属性
这两件事在 JavaScript 中效果完全不同:
-
修改原型对象内容(例如
Person.prototype.name = 'Alice')→ 所有未遮蔽该属性的已有实例立刻生效 -
替换 prototype 属性指向(例如
Person.prototype = { say() {} })→ 已创建的实例仍链接旧原型,完全不受影响
为什么改原型对象能立刻影响已有实例?
因为所有实例都通过内部 [[Prototype]] 槽(可读作 __proto__)**共享同一个原型对象引用**。属性访问不是“拷贝”,而是实时查找:
- 读取
obj.name时,JS 引擎先查obj自身是否有name - 没有就顺着
obj.__proto__去原型对象上找 - 原型对象变了内容,下次查找自然拿到新值
什么情况下修改会失效?
已有实例“看不到”变化,通常是因为:
- 实例自身已定义同名属性(遮蔽了原型上的属性)
- 你替换了整个
Person.prototype,但旧实例仍指向原来的原型对象 - 使用了
Object.create(null)或手动设置__proto__断开了标准链
instanceof 为什么有时会受影响?
instanceof 的判断逻辑是:沿着实例的 [[Prototype]] 链向上找,看是否出现右侧构造函数的 prototype 对象。所以:
- 如果只改原型对象内容(如加方法),
instanceof不变 - 如果替换了
Person.prototype,新创建的实例会指向新原型,instanceof结果可能变化;但旧实例仍连旧原型,判断结果不变

















