一、对象字面量须标注类型


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的这个一致,都无法让这种编译通过。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐