在JS中调用原型函数时出现意外结果

时间:2014-07-24 12:36:54

标签: javascript inheritance prototype

function Shape(color) {
    this.color = color;
}

Shape.prototype.draw = function() {
    return "Drew shape";
};

function Circle(color, radius) {
    Shape.apply(this, arguments);
    this.radius = radius;
}

Circle.prototype = Object.create(Shape.prototype);
Circle.prototype.draw = function() {
    return Object.getPrototypeOf(this).draw() + ", which was a circle";
};

var c = new Circle("red", 5);

除了调用c.draw():

之外,这大部分都按预期工作
c.draw(); // outputs "Drew shape, which was a circle, which was a circle"

这会按预期调用基类的draw(),但似乎也会调用对自身的额外递归调用!?发生了什么事?

John Resig将此作为实现超级方法的方法http://ejohn.org/blog/objectgetprototypeof/,但是如果你将一个console.log()添加到Norris的踢法中,你会发现它也被称为两次每次显式通话。

1 个答案:

答案 0 :(得分:0)

您需要了解thisCircle.prototype.draw的原型本身就是Circle.prototype。因此,它将再次返回Circle.prototype个对象。所以,电话

Object.getPrototypeOf(this).draw()

将缩减为

Circle.prototype.draw()

因此将再次调用相同的函数,但这次this将引用Circle.prototype,其原型是Shape.prototype对象。所以,

Object.getPrototypeOf(Circle.prototype).draw()

将评估为

Shape.prototype.draw()

首先评估最里面的调用,因此它首先返回Drew Shape,因为Circle的{​​{1}}函数被调用两次,它会打印{{1}两次。

要解决此问题,您只需致电父母draw,就像这样

which was a circle

我们可以像这样实现原型链

draw