修改构造函数的prototype会影响已实例化的对象吗?
问题解析:为何修改构造函数原型后旧实例能调用新方法
你疑惑的核心是对原型对象的引用关系理解有偏差,下面直接拆解原因:
1. 实例与原型的关系是「引用指向」,而非「复制」
当你用new Student()创建s1时,s1的__proto__(对应标准内部属性[[Prototype]]的浏览器暴露写法)是直接指向Student.prototype这个对象的引用,不是把原型对象的内容复制一份给s1。也就是说,s1和后续所有新实例的__proto__,都共享同一个Student.prototype对象。
2. 你只是修改了原型对象的属性,而非替换原型对象
你添加sayGoodbye的操作是:
Student.prototype.sayGoodbye = function() { ... }
这是在已有的Student.prototype对象上新增一个属性,并没有把Student.prototype换成一个全新的对象。此时s1的__proto__依然指向这个被修改过的原型对象,当调用s1.sayGoodbye()时,JS引擎会按原型链查找:
- 先在
s1自身找sayGoodbye,找不到 - 再去
s1.__proto__(也就是Student.prototype)找,此时这个对象已经有了sayGoodbye方法,所以能正常执行。
3. 只有替换整个原型对象时,旧实例才会失效
如果是直接替换Student.prototype为新对象:
// 替换整个原型对象 Student.prototype = { sayGoodbye: function() { console.log(`Goodbye, my name is ${this.name}`); } }
这时候s1的__proto__还是指向原来的原型对象(没有sayGoodbye),而新实例的__proto__才会指向这个新对象。此时调用s1.sayGoodbye()才会报错,符合你最初的认知。
总结
- 给原型对象新增/修改属性:所有新旧实例的原型链都能访问到,因为它们共享同一个原型对象引用
- 直接替换原型对象:旧实例的原型链还是指向旧对象,新实例指向新对象,二者不再共享更新
内容的提问来源于stack exchange,提问作者McBacon
相关产品推荐
相关产品推荐

