如何在构造函数的重载函数中使用子类的字段值

How to use field value from subclass in overloaded function in constructor

问题可以用这段代码来说明:

class A
{
    public readonly x;
    
    constructor()
    {
        this.x = this.getX();
    }

    protected getX()
    {
        return "X";
    }
}

class B extends A
{
    public readonly suffix = ko.observable("will change later");

    constructor()
    {
        super();        
    }

    protected getX()
    {
        return super.getX() + " " + this.suffix();
    }
}

console.log(new B().x);

结果是“X undefined”,这显然是不需要的,尽管考虑到 TypeScript 的“构建工作流程”这是预期的——主要是字段 suffix 只有在超级构造函数完成后才能获得它的值。但这是为什么呢?也许是因为在声明它时我们可以在“超级”实际存在之前使用“超级”东西?是先有鸡还是先有蛋的原则?

不幸的是,我 运行 多次陷入这个问题,有时我不得不重新设计一些东西来解决这个问题。如何解决这种“早期领域使用”?有没有已知的模式?

只有在完成 super 调用后才分配本地成员的当前方法看起来与您的 classes 无关。但它对于覆盖祖先成员的 classes 变得非常重要。

class A { x = 1 }
class B extends A { x = 2 }

分配 this.x = 2 before super 调用将导致非常不幸的后果。

我不完全了解此类问题的惯用解决方案。但是 getters/setters 看起来很适合最近可以初始化的 class 成员。

class A {
    public get x(): string { // implements readonly as it has no setter
        return this.getX()
    }

    protected getX(): string {
        return "X";
    }
}

class B extends A {
    public readonly suffix = "will change later";

    constructor() {
        super();        
    }

    protected getX() {
        return super.getX() + " " + this.suffix;
    }
}

console.log(new B().x); // "X will change later"

playground link