首页 文章

Prototypical Inheritance调用构造函数两次

提问于
浏览
6

我正在开发一个使用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,那么超类被调用两次,一次被传递到子类时 MySubClass.prototype = new MySuperClass(); 没有任何参数,一次参数在子类的构造函数中是'constructor stolen'时 .

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

现在,如果我这样做:

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

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

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

1 回答

  • 8

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

    MySubClass.prototype = MySuperClass;
    

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


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

    MySubClass.prototype = new MySuperClass();
    

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

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

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


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

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

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

相关问题