Javascript 如何在构造函数外部调用超级构造函数?
既然JavaScript有了类,我想知道如何在类构造函数之外调用超级构造函数 我未成功的天真尝试(导致语法错误): 我知道,在其他一些语言(如Java)中,超级构造函数只能在派生类的构造函数中调用,但ES6类是基于原型的继承的语法糖,因此如果使用内置语言特性不可行,我会感到惊讶。我就是想不出正确的语法 到目前为止,我所拥有的最好的东西感觉像是在作弊: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
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()
。