Typescript 在抽象类构造函数内部调用的抽象方法不';看不到派生类属性

Typescript 在抽象类构造函数内部调用的抽象方法不';看不到派生类属性,typescript,Typescript,下面的代码应该打印“Hello World!”在屏幕上。Insead打印错误:无法读取未定义的属性“id”。为什么? abstract class Parent { constructor() { console.log(this.getData()); } abstract getData(): string; } class Child extends Parent { constructor(private item: any) { super();

下面的代码应该打印“Hello World!”在屏幕上。Insead打印
错误:无法读取未定义的属性“id”
。为什么?

abstract class Parent {
  constructor() {
    console.log(this.getData());
  }

  abstract getData(): string;
}

class Child extends Parent {
  constructor(private item: any) {
    super();
  }

  getData(): string {
    return this.item.id;
  }
}

new Child({id: 'Hello World!'});

是一个工作示例。

问题是在
父类
构造函数中调用
getData
发生在将参数
item
分配给私有字段
item
之前。这是因为自动初始化发生在
super()
调用之后,而不是之前。请参见
***
注释:

abstract class Parent {
  constructor() {
    console.log(this.getData());  // *** Calls Child's getData
  }

  abstract getData(): string;
}

class Child extends Parent {
  constructor(private item: any) {
    super();                       // *** Calls Parent's constructor
    // ** Automatic initialization happens here, *after* the `super()` call
  }

  getData(): string {
    return this.item.id;           // *** So here, `this.item` is `undefined`
  }
}

new Child({id: 'Hello World!'});

这是从构造函数调用方法通常不是最佳实践的原因之一:它们可以被子类重写,但子类的初始化可能不完整(如您的情况)。

您有解决此问题的方法吗?现在我正在包装
getData()
调用
setTimeout
,但它看起来不太好。@Humberd-通常的解决方案是不从构造函数调用
getData
(听起来很不满意:-))。相反,将其留给子类来完成(理想情况下,也不是在其构造函数中)。您可以将构造函数重命名为
init()
,然后在子构造函数中调用
super.init()
。我测试了它,它works@CristianTraìna-最好也不要将其放入子构造函数中,除非它是最终类,即使这样,它也有点不可靠。。。这需要是一个建设后的步骤。我不应该在上面说“…让子类做…”。实际上,这是使用类的代码,在构建之后。@T.J.Crowder我的意思是在
super()
之前调用,然后
super.init()
,这会有什么问题?