You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 21:32:50