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

为什么继承Shape类时需要使用Shape.prototype而非Shape?

为什么继承Shape时需要使用Shape.prototype而不是直接用Shape?

嘿,这个问题问到点子上了!咱们来把这个逻辑掰扯明白,为什么这里非得用Shape.prototype,而不能直接赋值Shape给Rectangle.prototype。

首先得搞清楚JavaScript里构造函数和原型对象的核心区别:

  • Shape本身是一个构造函数,你用new Shape()创建实例的时候,这个函数负责初始化实例的自身属性(比如你的代码里的x和y)。但它本质上就是个普通函数,自身并没有包含move这类实例要共享的方法。
  • Shape.prototype才是所有Shape实例共享的原型对象,你定义的move方法就挂在这里——所有通过new Shape()创建的实例,都会通过原型链找到这个方法。

回到你的代码里的关键行:Rectangle.prototype = Object.create(Shape.prototype)
这一步的核心是让Rectangle的实例能继承Shape原型上的共享方法。Object.create(Shape.prototype)会创建一个新对象,这个新对象的原型指向Shape.prototype,然后把它赋值给Rectangle.prototype,这样Rectangle的实例就能顺着原型链找到move方法了。

那如果直接写Rectangle.prototype = Shape会怎么样?
那Rectangle的原型就变成了Shape这个构造函数本身,而不是它的原型对象。这时候Rectangle的实例会继承到的是函数对象自带的属性(比如length、name这些),完全找不到move方法——因为move根本不在Shape函数上,而是在Shape.prototype上。

你提到“Shape是基础类,没有继承属性”,其实就算是基础类,它的prototype依然是实例共享方法的“仓库”。继承的本质就是让子类的原型链连接到父类的原型对象上,这样才能拿到父类实例的共享能力。

另外补充一句:你代码里的Shape.call(this)是另一个关键——它是在Rectangle的构造函数里调用Shape的构造逻辑,给Rectangle的实例初始化x和y这些自身属性,和原型链继承共享方法的步骤是互补的,两者缺一不可。

举个反例对比一下:

// 错误写法:直接赋值Shape给Rectangle.prototype
function Rectangle() {
  Shape.call(this);
}
Rectangle.prototype = Shape;

const rect = new Rectangle();
rect.move(10, 20); // 会报错:rect.move is not a function

因为此时rect的原型是Shape函数,上面根本没有move方法;而用Shape.prototype的话,就能正常调用move啦。


内容的提问来源于stack exchange,提问作者O.O

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:50:17