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

Javascript 如何在构造函数外部调用超级构造函数?,javascript,class,inheritance,constructor,ecmascript-6,Javascript,Class,Inheritance,Constructor,Ecmascript 6,既然JavaScript有了类,我想知道如何在类构造函数之外调用超级构造函数 我未成功的天真尝试(导致语法错误): 我知道,在其他一些语言(如Java)中,超级构造函数只能在派生类的构造函数中调用,但ES6类是基于原型的继承的语法糖,因此如果使用内置语言特性不可行,我会感到惊讶。我就是想不出正确的语法 到目前为止,我所拥有的最好的东西感觉像是在作弊: class A { constructor() { this.a = 1; } } function initB() { let

既然JavaScript有了类,我想知道如何在类构造函数之外调用超级构造函数

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

我知道,在其他一些语言(如Java)中,超级构造函数只能在派生类的构造函数中调用,但ES6类是基于原型的继承的语法糖,因此如果使用内置语言特性不可行,我会感到惊讶。我就是想不出正确的语法

到目前为止,我所拥有的最好的东西感觉像是在作弊:

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

function initB()
{
    let newThis = new A();
    newThis.b = 2;
    return newThis;
}

class B extends A
{
    constructor() { return initB(); }
}
一个类的
扩展
某些的每个构造函数必须包含一个直接的
超级(…)
调用。
直接
super(…)
调用只能放在构造函数中。真的没办法

您确实不应该将类的初始化逻辑放在构造函数之外的任何地方。简单而正确的解决方案是根本不使用
initB

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

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

也就是说,有一种方法可以颠覆“
super()
调用必须在构造函数中”的要求。把它放在箭头函数中也很重要!所以你可以

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();
    }
}
这真的不是更好。

一个类的
扩展
某些的每个构造函数必须包含一个直接
超级(…)
调用。
直接
super(…)
调用只能放在构造函数中。真的没办法

您确实不应该将类的初始化逻辑放在构造函数之外的任何地方。简单而正确的解决方案是根本不使用
initB

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

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

也就是说,有一种方法可以颠覆“
super()
调用必须在构造函数中”的要求。把它放在箭头函数中也很重要!所以你可以

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();
    }
}

这真的不是更好。

是什么阻止你使用标准的
类B扩展了一个{constructor(){super();this.B=2;}}
,正如它应该的那样?你的“解决方案”实际上是一个语法错误。@Bergi我知道我的第一个方法是语法错误,这就是我为什么要问的原因。我澄清了我的问题,谢谢。实际上我是说第二个问题。是的,您的第一个代码段也是语法错误。构造函数不包含
super()
调用。例如,巴贝尔说得对。是什么阻止你使用标准的
类B扩展了一个{constructor(){super();this.B=2;}}
,正如它应该的那样?你的“解决方案”实际上是一个语法错误。@Bergi我知道我的第一个方法是语法错误,这就是我为什么要问的原因。我澄清了我的问题,谢谢。实际上我是说第二个问题。是的,您的第一个代码段也是语法错误。构造函数不包含
super()
调用。例如,巴贝尔说得对,“把它放在箭头函数中也很重要!”——这符合标准吗<代码>常量a=()=>{super()}
---这也愚弄了babel,但是能够避免调用父构造函数看起来很有破坏性:-为了澄清,只有当你想使用
this
@Oriol时才需要调用
super
,但是怎么样呢?这很有趣,但是babel从你的第二个例子中生成了破碎的JS。@Bergi我想你是在反向阅读早期错误中的否定,如果没有
extends
,则禁止使用
super()。“将其放入箭头函数也很重要!“---是否符合标准?
const a=()=>{super()}
——这也愚弄了babel,但是能够避免调用父构造函数看起来是破坏性的:-为了澄清,只有当你想使用
this
@Oriol时才需要调用
super
,但是怎么样呢?这很有趣,但是babel从你的第二个例子中生成了破损的JS。@Bergi我想你正在阅读否定在早期错误中,如果没有
extends
,则禁止使用
super()
,但只要在带有
extends
的类中返回显式值,则不需要使用
super()