打字稿:获得子属性从父构造
假定以下打字稿示例打字稿:获得子属性从父构造
class Animal {
public name: string;
constructor() {
console.log(this.name);
}
}
class Snake extends Animal {
public name = 'BeatSSS';
}
let someSnake = new Snake();
当然,的console.log日志undefined
。预计BeatSSS
。
我们怎样才能从父构造()与儿童属性做的事情?
实际的想法:儿童结构
- 超()()调用解决这个问题,但我需要做的每一个孩子。不是很优雅的解决方案
- 在父构造上使用超时记录正确的值,但不可能立即使用类的实例(尚未执行beacouse超时)。
我喜欢杰夫和邓肯已经提出的很多。不过,让我再展示一个选项。
abstract class Animal {
constructor(public name: string) {
console.log(this.name);
}
}
class Snake extends Animal { }
let someSnake = new Snake("Snakeeeey!");
注意这里的几件事情。
-
Animal
类似乎确实是一个抽象的概念。您可以选择将其标记为abstract
或将其定义为interface
,但后者不会让您有任何实现(包括构造函数)。 - TypeScript允许我们定义从构造函数初始化的字段。在公共财产的情况下,我们只需编写
constructor(public name: string)
。 -
Snake
类不明确明确定义了一个构造函数。然而,在创建蛇物品时,消费者必须提供Animal
类别所要求的name
参数。在Jeff的代码中,Snake类的
name
的默认值是constructor(name: string = 'BeatSSS') { super(name); }
。我不知道你的具体用例。如果没有任何有意义的默认名称为蛇,我会避免完全声明这样的构造函数。 -
邓肯正确地解释说,调用
super()
并非天生就是错误的。而且,这是必要的。当通过构造函数创建
Snake
类型的对象时,必须首先完成父(Animal
)的构造函数。因此,Animal
构造函数无法“查看”子项(Snake
)构造函数中发生的字段初始化的影响。由于构造函数调用的顺序,这是不可能的。因此,子类型为父类构造函数传递信息的唯一选项是直接调用
super(...)
。儿童construct()
super()
呼叫解决这个问题,但我需要做的每一个孩子。不是很优雅的解决方案
基本上没有完全定义子构造函数就是答案。如果您的孩子类必须具有构造函数,他们将强制您调用super()
作为the very first instruction。
在父构造上使用超时记录正确的值,但不能立即使用类的实例(beacouse超时尚未执行)。
这是一个非常糟糕的选择。首先,一般不建议在构造函数中有任何异步代码调用。
其次,如果你还做了在Animal
setTimeout(() => this.fixMyState(), 0)
构造它会导致不良的影响:对象构造后立即对象是在糟糕的状态。如果某些代码立即使用该对象会怎么样? () => this.fixMyState(), 0
甚至没有机会运行修复对象。建立后立即在良好状态中有一个对象是一条经验法则。否则,构造函数应该会出现错误throw
,这样就没有代码可以尝试对处于不良状态的对象进行操作。
如果你对每个孩子都需要这个,你应该把name参数传递给父类的构造函数。
什么是不是优雅的打电话给超级?你用其他语言做它,在打字稿中做什么错?
您正在设置一个属性,该类对于正确运行的类是固有的。通过构造函数设置这些属性。
abstract class Animal {
constructor(public name: string) {
}
}
class Snake extends Animal {
constructor(name: string = 'BeatSSS') {
super(name);
}
}
let someSnake = new Snake(); // use the default name 'BeatSSS'
let anotherSnake = new Snake('Foo'); // use a different name
class Dog extends Animal {
constructor(name: string = 'Rover') {
super(name);
}
}
let someDog = new Dog();
let anotherDog = new Dog('Bar');
当调用父构造函数时,对象尚未完全形成。它只是父母的一部分。这就是几乎所有的OOP语言的工作原理。 – 2017-10-21 18:53:36