ArkTs 字段初始化

4 阅读1分钟

为了减少运行时的错误和获得更好的执行性能,

ArkTS要求所有字段在声明时或者构造函数中显式初始化。这和标准TS中的strictPropertyInitialization模式一样。

以下代码是在ArkTS中不合法的代码。

class Person {
  name: string // undefined
  
  setName(n:string): void {
    this.name = n;
  }
  
  getName(): string {
    // 开发者使用"string"作为返回类型,这隐藏了name可能为"undefined"的事实。
    // 更合适的做法是将返回类型标注为"string | undefined",以告诉开发者这个API所有可能的返回值。
    return this.name;
  }
}

let jack = new Person();
// 假设代码中没有对name赋值,例如调用"jack.setName('Jack')"
jack.getName().length; // 运行时异常:name is undefined

ArkTS中,应该这样写代码。

class Person {
  name: string = ''
  
  setName(n:string): void {
    this.name = n;
  }
  
  // 类型为'string',不可能为"null"或者"undefined"
  getName(): string {
    return this.name;
  }
}
  

let jack = new Person();
// 假设代码中没有对name赋值,例如调用"jack.setName('Jack')"
jack.getName().length; // 0, 没有运行时异常

如果name的值可以是undefined,那么应该如何写代码

class Person {
  name?: string // 可能为`undefined`

  setName(n:string): void {
    this.name = n;
  }

  // 编译时错误:name可以是"undefined",所以将这个API的返回值类型标记为string
  getNameWrong(): string {
    return this.name;
  }

  getName(): string | undefined { // 返回类型匹配name的类型
    return this.name;
  }
}

let jack = new Person();
// 假设代码中没有对name赋值,例如调用"jack.setName('Jack')"

// 编译时错误:编译器认为下一行代码有可能会访问undefined的属性,报错
jack.getName().length;  // 编译失败

jack.getName()?.length; // 编译成功,没有运行时错误