为什么在 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"

您的变量在初始化期间被覆盖。属性初始化和构造函数执行顺序如下:

  1. 你的parentclass的构造函数执行并初始化memberHello World

  2. 你的childclass属性被初始化,覆盖之前初始化的成员变量。

  3. 你的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