这个问题我之前看过几次,但我认为我的问题更多的是关于这个的架构方法。
在 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) 使用 super
call
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/