我有一个用token初始化的类。
这个类然后初始化另一个类,它应该向这个类传递这个令牌。
我不明白为什么在主类构造函数之前调用第二个类构造函数。
有没有办法颠倒顺序?
谢谢。
// Main class
export class MainClass {
token: string;
constructor(t: string) {
console.log("MainClass constructor", t);
this.token = t;
}
private secondClass: SecondClass = new SecondClass(this.token);
}
// Second class
export class SecondClass {
constructor(t: string) {
console.log("SecondClass constructor",t);
}
}
// Client code
const app = new MainClass("1234");
// Console
--> "SecondClass constructor undefined"
--> "MainClass constructor 1234"
这个问题有点小问题,因为类字段在最终集成到ES2022规范之前就存在于TypeScript中,并且根据你的编译器设置(例如--useDefinedForClassFields
编译器选项),编译后的JavaScript可能会有一些不同的行为。但是我认为所有的版本都有相同的初始化顺序。
在类字段的MDN文档中说:
添加公共实例字段…要么在基类的构造时(在构造函数体运行之前),要么就在
super()
在子类中返回之后。
这意味着您可以期望类字段在constructor
主体中的代码之前被初始化。因此,您的代码或多或少与:
function MainClass(t) {
this.secondClass = new SecondClass(this.token);
console.log("MainClass constructor", t);
this.token = t;
}
或者
function MainClass(t) {
Object.defineProperty(this, "token", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "secondClass", {
enumerable: true,
configurable: true,
writable: true,
value: new SecondClass(this.token)
});
console.log("MainClass constructor", t);
this.token = t;
}
无论哪种方式,new SecondClass(this.token)
在this.token
设置为t
之前运行。
解决这个问题的方法是显式初始化构造函数体中的属性。这让您可以对顺序有更多的控制:
class MainClass {
token: string;
constructor(t: string) {
console.log("MainClass constructor", t);
this.token = t;
this.secondClass = new SecondClass(this.token);
}
private secondClass: SecondClass;
}
结果应该是预期的:
[LOG]: "MainClass constructor", "1234"
[LOG]: "SecondClass constructor", "1234"
Playground链接到代码