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

使用call()实现继承:为何其效果在后续创建实例时仍持续?

为啥调用call()后,新实例还能继承到方法?

嘿,这个问题刚好戳中了JavaScript原型机制和call()方法结合的核心,我给你一步步拆解清楚~

首先先把你提到的示例补全,方便对照着说:

// 定义一个混入函数,给对象添加圆形相关方法
var asCircle = function() {
  this.area = function() {
    return Math.PI * this.radius * this.radius;
  };
  this.grow = function() {
    this.radius += 1;
  };
  this.shrink = function() {
    this.radius -= 1;
  };
};

// 基础构造函数
function Shape(x, y) {
  this.x = x;
  this.y = y;
}

// 关键调用:把asCircle的this绑到Shape.prototype上
asCircle.call(Shape.prototype);

// 创建新实例
var myCircle = new Shape(10, 20);
myCircle.radius = 5;
console.log(myCircle.area()); // 输出约78.54

核心原因拆解:

  • call()的本质是改变this指向
    当你执行asCircle.call(Shape.prototype)时,你强制让asCircle函数内部的this指向了Shape.prototype这个对象。也就是说,asCircle里所有this.xxx = ...的赋值操作,其实都是在给Shape.prototype添加属性和方法——相当于把area、grow、shrink直接挂到了Shape的原型上。

  • 原型链的继承规则
    JavaScript中,用new Shape()创建的实例,它的内部原型(__proto__)会直接指向Shape.prototype。实例在访问某个方法时,会先看自己有没有,如果没有就顺着原型链往上找。只要Shape.prototype上有这些方法,不管实例是在call()调用前还是之后创建的,只要call()执行过,原型上的方法就已经存在了,后续的新实例自然能继承到这些方法。

  • 对比一下你可能误解的点
    你可能以为call()只是临时给某个对象加方法,但这里我们绑的是构造函数的原型对象,而原型对象是所有实例共享的“公共仓库”。一旦这个仓库里多了方法,所有后续创建的实例都能从仓库里拿到这些方法,这就是效果一直存在的原因。

如果还是有点懵,你可以把Shape.prototype想象成一个共享的工具箱:call()操作就是把asCircle里的工具(方法)放进这个工具箱里,之后所有新做出来的Shape实例(比如myCircle)都能直接用这个工具箱里的工具~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:10:30