在构造函数中使用已实现的成员(打字稿)
问题描述:
我发现在实现一个类时,实现的成员在构造函数中不可用。我不知道我是否执行错误,或者如果我真的应该采取不同的方法。在构造函数中使用已实现的成员(打字稿)
abstract class Parent {
abstract myVar: number;
constructor() {
console.log(this.myVar) // Outputs undefined
}
f() {
console.log(this.myVar) // outputs 5
}
}
class Child extends Parent {
myVar: number = 5;
}
let myChild = new Child;
myChild.f();
我该如何在构造函数中访问这些实现的成员?
答
基类的构造将无法在自己的执行过程中看到派生类的字段。
您可以使用此模式来代替:
abstract class Parent {
constructor(public myVar: number) {
console.log(this.myVar) // Outputs 5
}
f() {
console.log(this.myVar) // outputs 5
}
}
class Child extends Parent {
constructor() {
super(5);
}
}
let myChild = new Child;
myChild.f();
答
此:
class Child extends Parent {
myVar: number = 5;
}
等同于:
class Child extends Parent {
myVar: number;
constructor() {
super();
this.myVar = 5;
}
}
所以你首先调用超构造函数,在你试图访问其尚未分配myVar
。
这也是从编译JS明确:
var Parent = (function() {
function Parent() {
console.log(this.myVar);
}
Parent.prototype.f = function() {
console.log(this.myVar);
};
return Parent;
}());
var Child = (function (_super) {
__extends(Child, _super);
function Child() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.myVar = 5;
return _this;
}
return Child;
}(Parent));
如果您希望能够访问myVar
在Parent
构造函数,你可以这样做:
abstract class Parent {
abstract myVar: number;
constructor() {
this.init();
console.log(this.myVar);
}
f() {
console.log(this.myVar);
}
protected abstract init();
}
class Child extends Parent {
myVar: number;
protected init() {
this.myVar = 5;
}
}
不调用从构造一个虚拟的方法的忠实粉丝。派生类可能会调用一个基类方法,它的行为将是未定义的,因为基类仍处于部分初始化状态。 –
@RyanCavanaugh在大多数情况下,你是对的,但有时很难避免。无论如何,我在这里用它来说明事情发生的顺序。 –