如何在构造函数外调用超级构造函数?

时间:2016-03-28 23:51:41

标签: javascript class inheritance constructor ecmascript-6

现在JavaScript已经有了类,我想知道如何在类构造函数之外调用超级构造函数。

我未成功的天真尝试(导致语法错误):

Hash

我知道在像Java这样的其他语言中,超级构造函数只能在派生类的构造函数中调用,但ES6类是基于原型的继承的语法糖,所以我应该是如果使用内置语言功能不可行,我会感到惊讶。我似乎无法弄清楚正确的语法。

到目前为止,我遇到的最好的感觉非常像作弊:

class A
{
    constructor() { this.a = 1; }
}

function initB()
{
    super(); // How to invoke new A() on this here?
    this.b = 2;
}

class B extends A
{
    constructor() { initB.call(this); }
}

1 个答案:

答案 0 :(得分:6)

extends某些必须包含直接super(…)电话的类的每个构造函数。 直接super(…)调用只能放在构造函数中。真的没办法解决这个问题。

你真的不应该把一个类的初始化逻辑放在其他地方而不是它的构造函数中。直截了当且正确的解决方案是不要使用initB

class A {
    constructor() { this.a = 1; }
}

class B extends A {
    constructor() {
        super();
        this.b = 2;
    }
}

也就是说,有一种方法可以颠覆" super()调用必须在构造函数中#34;需求。把它放在箭头里面也很重要!所以你可以做到

class A {
    constructor() { this.a = 1; }
}

function initB(_super) {
    var b = _super();
    b.b = 2;
}
class B extends A {
    constructor() {
        initB(() => super());
    }
}

请允许我永远不要那样做。

另一种模式根本不是调用super(),只要从构造函数返回一个对象,它就会起作用。有了它,您可以将对象的实际构造放在其他任何位置:

class A {
    constructor() { this.a = 1; }
}

function makeB() {
    var b = Reflect.construct(A, [], B); // call the A constructor with B for the prototype
    b.b = 2;
    return b;
}
class B extends A {
    constructor() {
        return makeB();
    }
}

这真的不是更好。