初始化内联和初始化内部构造函数,这首先在 Typescript 中运行?

问题描述 投票:0回答:1

我正在学习打字稿中的类概念。我认识到有两种方法可以在打字稿中初始化字段(属性):内联初始化类主体和在构造函数方法内部初始化。我想知道初始化内联和初始化在另一个之前运行的构造函数内部。

我尝试了以下代码来测试,但我仍然不知道哪个先运行。

class Point{
    x :number = 0;
    y: number = 0;
    constructor();
    constructor(x:number,y?:number) ;
    constructor(x?:number,y?:number) {
        if(typeof x =='number') this.x = x;
        if(typeof y =='number') this.y = y
    }
}


let p = new Point(1);
console.log(`${p.x} ${p.y}`);

代码的结果是:

1 0
我用谷歌搜索了很多并阅读了一些其他问题(在声明期间内联初始化变量与在 Angular 中使用 TS 的构造函数),但我还没有找到答案。

感谢您考虑我的愚蠢问题。

typescript oop constructor initialization
1个回答
0
投票

类字段及其行为是 JavaScript 的一部分(从 ES2019 开始),即使您使用的是早期版本,TypeScript 通常也应该downlevel以保持相同的行为。 (这里有一个问题,因为 TypeScript 在 JavaScript 中存在之前就引入了类字段,并且 JavaScript 实现与 TypeScript 的假设有些不同,导致了

--target
编译器标志,但这并没有太大改变这里描述的行为)。 根据文档:“公共实例字段要么在基类的构造时(在构造函数主体运行之前)添加到实例中,要么在 --useDefineForClassFields
 在子类中返回之后添加到实例中。”
因此,一般来说:类字段声明上的初始化器发生在构造函数体内的赋值之前。

super()

在这里,我使用

逗号运算符 (
class Test {
    x: number = (console.log("field declaration"), 1)
    constructor() {
        this.x = (console.log("constructor body"), 2);
    }
}
const t = new Test();
//[LOG]: "field declaration" 
//[LOG]: "constructor body" 

console.log(t.x)
//[LOG]: 2 
)

在每次分配之前不久登录到控制台。您可以看到字段声明初始值设定项发生在构造函数赋值之前。

当你创建子类时,超类的东西首先发生,然后是子类的东西,但在这两种情况下,字段声明都发生在构造函数主体的其余部分之前:

,

可能
看起来像一个例外,因为超类构造函数在子类字段声明之前运行,事实上,如果您可以在调用

class SubTest extends Test { x: number = (console.log("field declaration subclass"), 3); constructor() { super(); this.x = (console.log("constructor body subclass"), 4) } } const s = new SubTest(); // [LOG]: "field declaration" // [LOG]: "constructor body" // [LOG]: "field declaration subclass" // [LOG]: "constructor body subclass" console.log(s.x) // [LOG]: 4 之前在子类构造函数主体中分配一个属性,那么它

是一个例外。  但这是被禁止的;在调用 
super() 之前,this 基本上不存在:
super()
因此:字段声明初始值设定项发生在同一类的构造函数主体中的赋值之前。

Playground 代码链接

© www.soinside.com 2019 - 2024. All rights reserved.