为什么在 parent 的构造函数中调用重载函数时,在 ES6 类 上设置属性不起作用
Why does setting properties on ES6 classes not work when calling an overloaded function in the constructor of the parent
我在写代码的时候遇到了这个我无法理解的场景。
场景如下:我有一个来自正在扩展的库的 class。
这个class就是“Parent”-class。它允许它的子 classes 覆盖 init-method 以进行自定义初始化。
第二个 child class 然而并不像我期望的那样。两者之间的唯一区别 classes 是成员变量的声明(?)。在编写纯 JS 时,我什至不会考虑这样做,但我正在用 Typescript 编写,这是编译结果(实际上,我什至没有在我的特定情况下分配值。TS 编译器只包含一个“成员; " 并且输出显示为 "undefined)
我很确定这个问题只发生在 parent 构造函数调用的覆盖函数中设置变量时。
有人可以向我解释为什么会这样吗?
class Parent {
constructor(initArgs) {
this.init(initArgs);
}
init() {}
}
class ChildTest1 extends Parent {
init(args) {
this.member = args;
}
test() {
console.log(`Member of ChildTest1 has value of "${this.member}"`);
}
}
class ChildTest2 extends Parent {
member = "default";
init(args) {
this.member = args;
}
test() {
console.log(`Member of ChildTest2 has value of "${this.member}"`);
}
}
new ChildTest1("Hello World").test();
new ChildTest2("Hello World").test();
输出如下:
Member of ChildTest1 has value of "Hello World"
Member of ChildTest2 has value of "default"
您的变量在初始化期间被覆盖。属性初始化和构造函数执行顺序如下:
你的parentclass的构造函数执行并初始化member
到Hello World
你的childclass属性被初始化,覆盖之前初始化的成员变量。
你的childclass构造函数执行
我已经使您的代码更加明确(请注意,添加 child 构造函数在功能上等同于您的示例)以证明这一点:
class Parent {
constructor(initArgs) {
this.init(initArgs);
console.log(`Parent Constructor: Member of ChildTest2 has value of "${this.member}"`);
}
init() {}
}
class ChildTest2 extends Parent {
member = "default";
constructor(initArgs) {
super(initArgs);
console.log(`Child Constructor: Member of ChildTest2 has value of "${this.member}"`);
}
init(args) {
this.member = args;
console.log(`Init: Member of ChildTest2 has value of "${this.member}"`);
}
test() {
console.log(`Test: Member of ChildTest2 has value of "${this.member}"`);
}
}
new ChildTest2("Hello World").test();
这会打印:
[LOG]: "Init: Member of ChildTest2 has value of "Hello World""
[LOG]: "Parent Constructor: Member of ChildTest2 has value of "Hello World""
[LOG]: "Child Constructor: Member of ChildTest2 has value of "default""
[LOG]: "Test: Member of ChildTest2 has value of "default""
作为心智模型,您可以假设 class 属性 初始化发生在构造函数内部的 super(...)
调用之后。更多相关信息 here
我在写代码的时候遇到了这个我无法理解的场景。
场景如下:我有一个来自正在扩展的库的 class。 这个class就是“Parent”-class。它允许它的子 classes 覆盖 init-method 以进行自定义初始化。
第二个 child class 然而并不像我期望的那样。两者之间的唯一区别 classes 是成员变量的声明(?)。在编写纯 JS 时,我什至不会考虑这样做,但我正在用 Typescript 编写,这是编译结果(实际上,我什至没有在我的特定情况下分配值。TS 编译器只包含一个“成员; " 并且输出显示为 "undefined)
我很确定这个问题只发生在 parent 构造函数调用的覆盖函数中设置变量时。
有人可以向我解释为什么会这样吗?
class Parent {
constructor(initArgs) {
this.init(initArgs);
}
init() {}
}
class ChildTest1 extends Parent {
init(args) {
this.member = args;
}
test() {
console.log(`Member of ChildTest1 has value of "${this.member}"`);
}
}
class ChildTest2 extends Parent {
member = "default";
init(args) {
this.member = args;
}
test() {
console.log(`Member of ChildTest2 has value of "${this.member}"`);
}
}
new ChildTest1("Hello World").test();
new ChildTest2("Hello World").test();
输出如下:
Member of ChildTest1 has value of "Hello World"
Member of ChildTest2 has value of "default"
您的变量在初始化期间被覆盖。属性初始化和构造函数执行顺序如下:
你的parentclass的构造函数执行并初始化
member
到Hello World
你的childclass属性被初始化,覆盖之前初始化的成员变量。
你的childclass构造函数执行
我已经使您的代码更加明确(请注意,添加 child 构造函数在功能上等同于您的示例)以证明这一点:
class Parent {
constructor(initArgs) {
this.init(initArgs);
console.log(`Parent Constructor: Member of ChildTest2 has value of "${this.member}"`);
}
init() {}
}
class ChildTest2 extends Parent {
member = "default";
constructor(initArgs) {
super(initArgs);
console.log(`Child Constructor: Member of ChildTest2 has value of "${this.member}"`);
}
init(args) {
this.member = args;
console.log(`Init: Member of ChildTest2 has value of "${this.member}"`);
}
test() {
console.log(`Test: Member of ChildTest2 has value of "${this.member}"`);
}
}
new ChildTest2("Hello World").test();
这会打印:
[LOG]: "Init: Member of ChildTest2 has value of "Hello World""
[LOG]: "Parent Constructor: Member of ChildTest2 has value of "Hello World""
[LOG]: "Child Constructor: Member of ChildTest2 has value of "default""
[LOG]: "Test: Member of ChildTest2 has value of "default""
作为心智模型,您可以假设 class 属性 初始化发生在构造函数内部的 super(...)
调用之后。更多相关信息 here