typescript - 从父构造函数访问子属性

标签 typescript

假设以下 Typescript 示例

class Animal {
    public name: string;

    constructor() {
        console.log(this.name);
    }
}

class Snake extends Animal {
    public name = 'BeatSSS';
}

let someSnake = new Snake();

当然,console.log() 记录 undefinedBeatSSS 是预期的。

我们如何从父 constructor() 中用子属性做事?

实际想法:

  • super() 调用 child construct() 解决了问题,但我需要对每个 child 都这样做。不是很优雅的解决方案。
  • 在父构造上使用超时记录正确的值,但不可能立即使用类的实例(因为超时尚未执行)。

最佳答案

我非常喜欢 Jeff 和 Duncan 已经提出的建议。不过,让我再展示一个选项。

abstract class Animal {
    constructor(public name: string) {
        console.log(this.name);
    }
}

class Snake extends Animal { }

let someSnake = new Snake("Snakeeeey!");

请注意这里的一些事情。

  • Animal 类似乎确实是一个抽象概念。您可以选择将其标记为 abstract 或将其定义为 interface,但后者不会让您有任何实现(包括构造函数)。
  • TypeScript 允许我们定义从构造函数初始化的字段。对于公共(public)属性,我们只需编写 constructor(public name: string)
  • Snake 类没有显式定义构造函数。然而,在创建蛇对象时,消费者必须提供Animal 所需的name 参数。

    在 Jeff 的代码中,Snake 类有一个 name 的默认值,这是通过 constructor(name: string = 'BeatSSS') { super(name); 实现的。 }。我不知道你的具体用例。如果蛇没有任何有意义的默认名称,我会完全避免声明此类构造函数。

  • Duncan 正确地解释了调用 super() 本身并不是错误的。而且,这是必要的。

    Snake 类型的对象通过其构造函数创建时,父(Animal)的构造函数必须首先完成。因此,Animal 构造函数无法“看到”发生在子(Snake)构造函数中的字段初始化效果。由于构造函数调用的顺序,这是不可能的。

    因此,子类型传递父类构造函数信息的唯一选择是直接调用 super(...)


super() call on child construct() solve the problem, but I need do it on every child. Not very elegant solution.

基本上完全不定义子构造函数就是答案。如果您的子类必须拥有构造函数,他们将强制您调用super() 作为the very first instruction .

using a timeout on parent construct logs the correct value, but is not possible use the instance of class immediately (beacouse timeout is not executed yet).

这是一个非常糟糕的选择。首先,通常不建议在构造函数中调用任何异步代码。

其次,如果您仍然在 Animal 构造函数中执行 setTimeout(() => this.fixMyState(), 0) 会导致不好的效果:紧接着对象构造,对象处于错误状态。如果某些代码立即使用该对象怎么办? () => this.fixMyState(), 0 甚至没有机会运行以修复对象。根据经验,对象在构建后立即处于良好状态 是一种经验法则。否则,构造函数应该抛出一个错误,这样就没有代码可以尝试对处于错误状态的对象进行操作。

关于typescript - 从父构造函数访问子属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46866467/

相关文章:

javascript - Angular 2 Facebook 登录

reactjs - 如何键入可选的空对象

返回 subject.asObservable() 时的 typescript 错误

typescript - 使用 get/set 访问器而不是标准的 getter/setter 方法有什么好处?

javascript - Chart.js 图例位置错误

javascript - 我可以在 typescript 中使用什么来显示两个接口(interface)的值之间的关系

node.js - Express.js 和 Mongoose : access Object attribute name by the request parameter

javascript - 如何从一个组件获取另一个组件的值(value)?

css - 如何从一组颜色中动态地脉动文本颜色?

javascript - Angular Subscribe 在值更改之前不起作用(需要首先初始化)