Prototypical Inheritance调用构造函数两次

obi*_*bie 6 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();
Run Code Online (Sandbox Code Playgroud)

重点是继承.

这个问题是,如果我在每个类(超级和子类)的构造函数中放置一个console.log,那么超级类被调用两次,一次被传递到MySubClass.prototype = new MySuperClass();没有任何参数的子类,一次带参数当它是子类的构造函数中的"构造函数被盗"时.

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

现在,如果我这样做:

var MySubClass = function (param) {
    MySuperClass.call(this, param);
};
MySubClass.prototype = MySuperClass;
MySubClass.prototype.constructor = MySubClass;
Run Code Online (Sandbox Code Playgroud)

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

任何人都可以向我解释第二个是否以及如何不正确(它似乎与Crockford继承功能相似)以及如果它取悦,如何修复第一个不发射两次?

I H*_*azy 8

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

MySubClass.prototype = MySuperClass;
Run Code Online (Sandbox Code Playgroud)

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


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

MySubClass.prototype = new MySuperClass();
Run Code Online (Sandbox Code Playgroud)

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

MySubClass.prototype = Object.create(MySuperClass.prototype);
Run Code Online (Sandbox Code Playgroud)

现在你有一个分配给MySubClass.prototype它的对象继承自MySuperClass.prototype,但你永远不必实际调用构造函数.


非ES5兼容的实现不支持Object.create,但您可以为它制作(部分)垫片.

if (!Object.create) {
    Object.create = function(proto) {
        function F(){}
        F.prototype = proto;
        return new F();
    };
}
Run Code Online (Sandbox Code Playgroud)

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