为了减少运行时的错误和获得更好的执行性能,
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; // 编译成功,没有运行时错误