在javascript中继承并使用超类的构造函数

时间:2014-09-04 18:31:55

标签: javascript inheritance

我想知道是否可以通过自动使用超类的构造函数在javascript中实例化子类。
考虑一下(灵感来自this other question here on SO):

function A(prop) {
    this.prop = prop;
}
A.prototype.whatAmI = function() {
    console.log(
        "I'm an instance of %s, my prop is %s",
        this instanceof A1? "A1" : "A2",
        this.prop
    );
};

function A1() {
    A.apply(this, arguments);
}
A1.prototype = new A();
A1.prototype.constructor = A1;

function A2() {
    A.apply(this, arguments);
}
A2.prototype = new A();
A2.prototype.constructor = A2;

var a1 = new A1("foo").whatAmI(); //I'm an instance of A1, my prop is foo
var a2 = new A2("bar").whatAmI(); //I'm an instance of A2, my prop is bar

但是,参考this article,在第一个例子中,我遇到了这行代码:

Cat.prototype.constructor = Cat;
//Otherwise instances of Cat would have a constructor of Mammal

我认为这正是我所需要的:A1A2的实例具有A的构造函数。很遗憾,评论A1.prototype.constructor = A1并清空A1的正文(同样适用于A2)不起作用:

function A1() {}
A1.prototype = new A();

function A2() {}
A2.prototype = new A();

var a1 = new A1("foo").whatAmI(); //I'm an instance of A1, my prop is undefined
var a2 = new A2("bar").whatAmI(); //I'm an instance of A2, my prop is undefined

最后,将A的构造函数更改为使用arguments对象而不是显式传递prop也不会产生任何影响:

function A() {
    this.prop = arguments[0];
}

甚至可以通过prototype属性稍微摆弄来实现我想要的目标吗?

1 个答案:

答案 0 :(得分:4)

Cat.prototype.constructor = Cat;
//Otherwise instances of Cat would have a constructor of Mammal
     

我认为这正是我所需要的:A1和A2的实例   有A的构造函数。

不,那不是他们的意思。 A1A2函数 仍然是他们自己被调用的构造函数,你无法改变它。

本文描述的问题是,当您覆盖.constructor时,所有实例都继承以指出其构造函数AX.prototype属性不再有效。另请参阅What is the `constructor` property really used for?(及相关问题)。

  

不幸的是评论A1.prototype.constructor = A1和   清空A1的身体(同样适用于A2)不起作用。

通过清空身体,它不再做任何事情了。你仍然需要明确地致电A,你不会解决这个问题。您可以做的是创建一个通用工厂,为A创建不做任何特殊操作的子类,但我认为它不值得。

哦,不要忘记:You should not use new for creating prototypes

subclass(parent) {
    function Child() {
        parent.apply(this, arguments);
    }
    Child.prototype = Object.create(parent.prototype);
    Child.prototype.constructor = Child;
    return Child;
}

function A(prop) {
    this.prop = prop;
}
A.prototype.whatAmI = function() {
    console.log(
        "I'm an instance of %s, my prop is %s",
        this instanceof A1? "A1" : "A2",
        this.prop
    );
};
var A1 = subclass(A),
    A2 = subclass(A);