一、对象字面量须标注类型
const point = {
x: 100,
y: 100
}
console.log(point)
运行之后会输出
{ x: 100, y: 100 }
以上TS代码片段展示了没有类型的场景。如果编译器不知道变量point的确切类型,由于对象布局不能确定,编译器无法深度地优化这段代码,造成性能瓶颈。没有类型也会造成属性的类型缺少限制,例如point.x的类型在此时为number,它也可以被赋值成其他类型,造成额外的运行时检查和开销。
在ArkTS中,需要为对象字面量标注类型。
如果在ArkTS文件中这么写的话,编辑器会自动提示必须要标注类型,否则无法通过编译。
参考:初识ArkTS语言 | 华为开发者联盟
至于这篇文档中提到的第一点「不支持在运行时更改对象布局」,其实TS的编译器检查,示例代码编译也没法编译通过:
运行以后会提示:
所以华为官网提到的第一点算不上是不同,而是相同的编译检查。
要想绕过其中的编译安全检查,需要转成any对象以后才可以
class Point {
public x: number
public y: number
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
}
let p1 = new Point(1, 2)
console.log("init " + "p1.x = " + p1.x + " p1.y = " + p1.y)
// 使用类型断言确保可以删除属性
delete (p1 as any).x
console.log("delete " + "p1.x = " + p1.x + " p1.y = " + p1.y)
let p2 = new Point(3, 4);
console.log("init " + "p2.x = " + p2.x + " p2.y = " + p2.y);
// 使用类型断言确保可以添加属性
(p2 as any).z = 4;
console.log("add " + "p2.x = " + p2.x + " p2.y = " + p2.y + " p2.z = " + (p2 as any).z);
在ArkTS中,可以使用可选属性和给该属性赋值undefined的方式来替代。
华为官方文档中提到的第三点「structural typing」
class Car {
str: string = "Car Text"
}
class Bus {
num: number = 0
str: string = ""
}
function foo(bus: Bus) {
console.log(bus.str)
}
foo(new Car());
运行示例代码:
运行之后,会提示:
由此可见,其实TS也对这个进行了编译检查,不会让这种编译通过,ArkTS的特性和TS的这个一致,都无法让这种编译通过。