原型对象互换是重设构造函数的prototype属性以影响后续实例,已存在实例不受影响;正确做法是直接赋值新对象并补回constructor;可共享方法对象实现多构造函数复用;慎用object.setprototypeof修改单个实例原型。

原型对象互换不是“切换实例的原型”,而是重设构造函数的 prototype 属性,从而让后续创建的实例自动关联到新原型。这个操作会影响新实例,但对已存在的实例无影响——因为每个实例的 __proto__ 在 new 时就已绑定完成,不会随构造函数 prototype 的变更而更新。
替换构造函数的 prototype 是核心操作
直接给构造函数赋值一个新对象,就能改变其后续实例的原型指向:
-
正确做法:
Person.prototype = { say() { console.log('hi'); } }; - 之后再执行
new Person(),新实例的__proto__就会指向这个新对象 - 注意:原
Person.prototype.constructor会丢失,建议手动补回:Person.prototype.constructor = Person;
已存在实例不受影响
替换前创建的实例,__proto__ 仍指向旧的 Person.prototype,两者完全独立:
-
const p1 = new Person();→p1.__proto__ === 旧 prototype - 执行
Person.prototype = {...}后 -
const p2 = new Person();→p2.__proto__ === 新 prototype -
p1.__proto__ === p2.__proto__返回false
想让多个构造函数共享同一套方法?用对象复用
把方法定义在一个普通对象里,然后让不同构造函数的 prototype 指向它:
const sharedMethods = { walk() { console.log('walking'); } };Dog.prototype = sharedMethods;Cat.prototype = sharedMethods;- 这样
new Dog()和new Cat()都能调用walk,且共用同一份函数体
慎用 Object.setPrototypeOf() 直接改实例原型
虽然可以临时修改单个实例的 __proto__(如 Object.setPrototypeOf(p, NewProto)),但这属于运行时干预,性能差、不可预测,且破坏原型链稳定性:
- 仅适合调试或极特殊场景
- 不推荐用于常规方法共享或继承设计
- 现代代码应优先通过构造函数 prototype 统一控制











