inheritance - TypeScript:在派生类的构造函数中访问 'super' 之前必须先调用 'this'

标签 inheritance architecture typescript webstorm typescript1.8

这个问题我之前看过几次,但我认为我的问题更多的是关于这个的架构方法。
在 TypeScript 中,不可能在调用 super 之前使用 this 关键字(在从另一个类扩展的类上)。
但是,如果您需要执行以下示例中的操作怎么办?
(澄清一下:我正在为 UI 库创建组件生命周期,所以感觉我真的需要做这样的事情,而且我似乎想不出任何其他方法来解决这个问题)。

代码

我想做的是:

class Person 
{
    public firstName: string;

    constructor()
    {
        this.scream();
    }

    protected scream(): void
    {
        console.log(this.firstName);
    }
}

class Employee extends Person
{
    public lastName: string;

    constructor(firstName: string, lastName: string)
    {
        this.lastName = lastName;
        super(firstName);
    }

    protected scream(): void
    {
        console.log(this.firstName + ' ' + this.lastName);
    }
}

问题

父类'Person'的构造函数调用了一个 protected 方法。
子类“Employee”想要在覆盖此 protected 方法时使用自己的参数 (this.lastName)。
但是上面的代码抛出错误(至少在 Webstorm 中):
“在派生类的构造函数中访问‘this’之前必须先调用‘super’”

可能的解决方案

A) 使用 supercall

切换 this.lastName = lastName
class Employee extends Person
{
    ...

    constructor(firstName: string, lastName: string)
    {
        super(firstName);
        this.lastName = lastName;
    }

    ...
}

=> 这里的问题是 this.lastName 将在类“Employee”的 scream() 方法中被undefined

B)
使用 setTimeout(callback, 0)。 这样以后就会调用 this.scream() 方法。

class Person 
{
    ...

    constructor()
    {
        setTimeout(() => this.scream(), 0);
    }

    ...
}

=> 但对我来说,这感觉就像是一个非常丑陋的 hack。

C)
不要从 Person 类内部调用 this.scream(),而是从消费者调用它。

const employee: Employee = new Employee();
employee.scream();

=> 但显然这并不总是您想要的。

问题

  • 我是不是在做傻事?
  • 有没有更好的方法来安排我的代码,这样我就不需要这样做了?
  • 有什么方法可以解决这个错误吗?

最佳答案

除了@iberbeu 和@Nypan 提供的解决方案之外,我最终想到的另一个解决方案是在调用 scream( ):

class Person 
{
    public firstName: string;

    constructor(firstName: string, props?: any)
    {
        this.firstName = firstName;
        this.initProps(props);
        this.scream();
    }

    protected initProps(props: any): void
    {
    }

    protected scream(): void
    {
        console.log(this.firstName);
    }
}

class Employee extends Person
{
    public lastName: string;

    constructor(firstName: string, lastName: string)
    {
        super(firstName, {lastName});
    }

    protected initProps(props: any): void
    {
        this.lastName = props.lastName;
    }

    protected scream(): void
    {
        console.log(this.firstName + ' ' + this.lastName);
    }
}

虽然我认为两者都提出了一个重点,但我实际上应该改用工厂模式..

关于inheritance - TypeScript:在派生类的构造函数中访问 'super' 之前必须先调用 'this',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37523282/

相关文章:

C++基础架构设计

javascript - 开发 SPA 的最佳方法是什么?

css - Snackbar 动态颜色变化 Angular 7

python - 如何在 BaseClass 方法被 Python 中的 DerivedClass 方法覆盖之前执行它

java - 在继承类的 super 方法中返回 `this`

c++ - 多态性和对象存储

javascript - 解构嵌套对象 es6

c++ - 观察者设计模式接口(interface)契约设计问题

mysql - 如何有效地对基于时间的数据集进行分组以计算组平均值和中位数

javascript - 无法从选择框中选择项目/在输入字段中写入。我是否错误地处理了 'key'?