Prototypical Inheritance调用构造函数两次

时间:2012-11-02 15:56:27

标签: javascript inheritance prototypal-inheritance

我正在开发一个使用Prototypical Inheritance的JavaScript项目。我决定使用它的方式如下:

var MySuperClass = function (param) {
    this.prop = param;
};
MySuperClass.prototype.myFunc = function () {
    console.log(this.prop);
};

var MySubClass = function (param) {
    MySuperClass.call(this, param);
};
MySubClass.prototype = new MySuperClass();
MySubClass.prototype.constructor = MySubClass;

var obj = new MySubClass('value');
obj.myFunc();

强调继承。

这个问题是,如果我在每个类(super和sub)的构造函数中放入一个console.log,那么超类被调用两次,一次被传递到子类{{1}在子类的构造函数中,当“构造函数被盗”时,没有任何参数和一次参数。

如果我尝试保存这些参数(这意味着我必须添加逻辑来处理空参数),这可能会导致错误。

现在,如果我这样做:

MySubClass.prototype = new MySuperClass();

一切似乎都正常工作但我以前从未见过有人这样做过(在我的Googl'ing中)。

任何人都可以向我解释第二个是否以及如何不正确(它似乎与Crockford继承功能相似)以及如果第一个不能解决,如果它是好的话,该怎么解决?

1 个答案:

答案 0 :(得分:8)

这样做不是一个正确的解决方案:

MySubClass.prototype = MySuperClass;

您将函数本身设置为原型而不是原型对象,因此您不会继承您期望的内容。


但你是对的。这样做会调用构造函数,这会导致问题。

MySubClass.prototype = new MySuperClass();

解决方案是使用Object.create来设置继承。它为您提供了一个从提供的对象继承的新对象,但不会调用任何构造函数。

MySubClass.prototype = Object.create(MySuperClass.prototype);

现在,您有一个从MySubClass.prototype继承的MySuperClass.prototype对象,但您永远不必实际调用构造函数。


非ES5兼容的实现不支持Object.create,但您可以为其创建(部分)填充程序。

if (!Object.create) {
    Object.create = function(proto) {
        function F(){}
        F.prototype = proto;
        return new F();
    };
}

同样,这不是一个完整的填充程序,但它模拟的足以能够创建继承的对象而无需调用引用原型对象的构造函数。