Object.create()与直接赋值原型的区别及原型共享问题解惑
原型引用导致的方法覆盖问题解释
问题代码
function Student() { } Student.prototype.sayName = function() { console.log(this.name) } function EighthGrader(name) { this.name = name this.grade = 8 } EighthGrader.prototype = Student.prototype function NinthGrader(name) { this.name = name this.grade = 9 } NinthGrader.prototype = Student.prototype NinthGrader.prototype.sayName = function() {console.log("HAHAHAHAHAHA")} const carl = new EighthGrader("carl") carl.sayName()
用户疑问
我查阅了MDN上Object.create()的文档,但仍无法理解:为何修改NinthGrader的原型对象方法后,调用carl.sayName()会输出"HAHAHAHAHAHA"而非"carl"?
问题解析
核心原因是所有构造函数的原型指向了同一个内存对象:
你直接把EighthGrader.prototype和NinthGrader.prototype赋值为Student.prototype,这不是复制原型,而是让三个构造函数的原型都共享同一个对象——也就是Student.prototype本身。
所以当你修改NinthGrader.prototype.sayName时,本质上是在修改Student.prototype上的sayName方法。而carl作为EighthGrader的实例,它的原型链最终指向的就是Student.prototype,调用sayName时自然会使用这个被修改后的方法,输出"HAHAHAHAHAHA"。
如果要让不同年级的学生原型相互独立,同时继承Student的方法,应该用Object.create(Student.prototype)创建新的原型对象,而非直接赋值引用。示例代码如下:
function Student() {} Student.prototype.sayName = function() { console.log(this.name); }; function EighthGrader(name) { this.name = name; this.grade = 8; } // 创建独立的原型对象,继承Student的原型方法 EighthGrader.prototype = Object.create(Student.prototype); // 修复constructor指向(可选但推荐) EighthGrader.prototype.constructor = EighthGrader; function NinthGrader(name) { this.name = name; this.grade = 9; } NinthGrader.prototype = Object.create(Student.prototype); NinthGrader.prototype.constructor = NinthGrader; // 修改NinthGrader的sayName,不会影响EighthGrader NinthGrader.prototype.sayName = function() { console.log("HAHAHAHAHAHA"); }; const carl = new EighthGrader("carl"); carl.sayName(); // 输出"carl"
内容的提问来源于stack exchange,提问作者Syed Faheem
相关产品推荐
相关产品推荐

