1. 背景
- 为什么设计ArkTS?
1.1 其它语言有版权【Java?Kotlin?】以及历史问题【Java内存?】
1.2 生态,可复用前端生态的三方库,兼容JS/TS语言生态- ArkTs解决了JS/TS中的哪些问题?
2.1 **程序健壮性:**JS是动态类型【运行期间才去做数据类型检查,且类型可以随便改变】,不利于程序的健壮性。
2.2 **性能问题:**TS虽然是静态类型,但是它的类型检查可配置可关闭,而且编译后类型信息丢失,会增加运行的时编译和执行字节码耗时。ArkCompiler利用ArkTS的静态类型信息,进行类型推导并生成对象描述和内联缓存,**加速运行时对字节码的解释执行;**AOT(Ahead-of-Time)Compiler利用静态类型信息直接将字节码编译生成优化机器码,让应用启动即可运行高性能代码,提升应用启动和运行性能。
2.3 JS运行流程: 解析源码>编译字节码>执行字节码>获取Profile信息>编译优化机器码>执行优化机器码
2.4 ArkTS编译流程: 解析源码>编译字节码>获取Profile信息>编译优化机器码>打包字节码和优化字节码
2.5 ArkTS运行流程: 执行优化机器码>执行字节码
2.6 安全: ArkCompiler会把ArkTS/TS/JS编译为方舟字节码,运行时直接运行方舟字节码。并且ArkCompiler使用多种混淆技术提供更高强度的混淆与保护,使得HarmonyOS应用包中装载的是多重混淆后的字节码,有效提高了应用代码安全的强度。
2.7 并发: JS/TS 中并发的API不够简洁,而且支撑不了复杂业务的开发场景,而ArkTS中的TaskPool会绑定系统的调度优先级,并且支持负载均衡(自动扩缩容),可支撑各种业务场景
2. 前言
无论是Android还是iOS开发,都提供了多种数据类型用于常见的业务开发,和Java/Objective-C一样ArkTs也有很多和Java/Objective-C中相同的数据类型,当然也有不同的。
ArkTS和JS\TS之间的关系
关于ES 是什么,可以看我这边整理的一篇文章 Javascript[ECMAScript] ES6、ES7、ES8、ES9、ES10、ES11、ES12、ES13、ES14[2023]新特性
ArkTS是TypeScript的超集,其数据类型也是基于TypeScript而来,除了原始5种数据类型之外,还有一些 ECMAScript 中的新类型,以及包含常见的枚举、任意类型等等,大概有十多种,但常用的就那么几种。
数据类型汇总如下:
数据类型 | 包装类 | 概述 |
---|---|---|
number | Number | 数字类型 |
boolean | Boolean | 布尔类型 |
string | String | 字符串类型 |
object | Object | 对象 |
Array | Array | |
tuple | 元组类型 | |
enum | 枚举类型 | |
union | 联合类型 | |
undefined | 一个未定义或不存在的值 | |
null | 空 | |
aliases | 匿名类型 | |
BigInt | 任意大的数 | |
void | 没有任何返回值的类型 |
为了保证开发正确性和性能,ArkTS中取消了JS中的symbol类型,以及TS中的unknown 和any类型
3. 类型声明
3.1 变量声明
以关键字let开头的声明引入变量,该变量在程序执行期间可以具有不同的值。【注意,这里不能使用JS/TS中的var,因为let关键字可以在块级作用域中声明变量,帮助程序员避免错误。因此,ArkTS不支持var,请使用let声明变量。】
这里的let 类似于kotlin中的var
let hi: string = 'hello';
hi = 'hello, world';
3.2 常量声明
以关键字const开头的声明引入只读常量,该常量只能被赋值一次。对常量重新赋值会造成编译时错误。
这里的const 类似于kotlin中的val
const hello: string = 'hello';
3.3 自动类型推断
由于ArkTS是一种静态类型语言,所有数据的类型都必须在编译时确定。
但是,如果一个变量或常量的声明包含了初始值,那么开发者就不需要显式指定其类型。ArkTS规范中列举了所有允许自动推断类型的场景。
以下示例中,两条声明语句都是有效的,两个变量都是string类型
let hi1: string = 'hello';
let hi2 = 'hello, world';
//使用JS的同学注意了:这里和JS不一样,ArkTS中一旦类型初始化的时候就确定了,之后就无法更改。例如:
// hi2 = 123// 错误
flag = '你好世界' //正确
4. 基础数据类型
JavaScript中存在两套类型系统分别为原生类型(Base types)和对象类型(Object types)【类似于Java中装箱和拆箱】,ArkTS也继承了这一特性。
对象类型和原生类型相比,会提供一些额外的方法,例如string和String
let msg: string = 'Hello world!';
let msg2: String = 'Hello world!';
let msg22 = 'Hello world!'; //字面上没有定义类型
let msg3: String = new String('Hello world!');
console.log(typeof(msg)); //string
console.log(typeof(msg2)); //string
console.log(typeof(msg22)); //string
console.log(typeof(msg3)); //object
console.log((msg === msg2)+""); //true
console.log((msg === msg3)+""); //false
console.log((msg2 === msg3)+""); //false
4.1 Number类型
凡是表示数值的,不管是二进制还是八进制,还是其他进制,长整数,小数,负数等等,只有一个类型表示,那就是number。
局部声明须带关键字
4.1.1 原生number
let a: number = 0 //整数
let b: number = -100 //负数
let c: number = 88.88 //小数
let d: number = 0b1010 //二进制 ES6
let e: number = 0o744 //八进制 ES6
4.1.2 对象Number
let a: Number = new Number(0) //整数
let b: Number = new Number(-100) //负数
let c: Number = new Number(88.88) //小数
let d: Number = new Number(0b1010) //二进制 ES6
let e: Number = new Number(0o744) //八进制 ES6
4.1.3 上限
在ArkTS中,Number类型的上限由JavaScript的Number类型的上限决定,因为ArkTS的Number类型是基于JavaScript的Number类型。
JavaScript中的Number类型是基于IEEE 754标准的双精度浮点数表示,它的上限由标准规定为1.7976931348623157e+308。这意味着JavaScript中的Number类型可以表示的最大值是约1.8 x 10^308。
const maxNumber: number = Number.MAX_VALUE;
console.log(maxNumber.toString()); // 输出 1.7976931348623157e+308
const infinity: number = Number.MAX_VALUE * 2;
console.log(infinity.toString()); // 输出 Infinity
【必看】注意注意:
因为ArkTS的Number类型是基于JavaScript的Number类型。那么在JS中著名精度丢失问题,在ArkTS中也依旧存在,这里想起一张图。。。此处先只解决图里面精度丢失的问题,其它问题后续会出详细的文档来说明和解决。
**解决办法:**可以用成熟的三方库来解决:https://ohpm.openharmony.cn/#/cn/detail/bignumber.js
【鸿蒙版的bigNumber】
**问题原因:**可看这个https://juejin.cn/post/7216917459009536060
// Demo 1 - 乘法异常
console.log(18.9 * 100+"") // 1889.9999999999998
console.log(64.68 * 100+"") // 6468.000000000001
// Demo 2
// 典中典
console.log((0.1 + 0.2 === 0.3)+"") // false
console.log((0.1 === 0.1)+"") // true
....等等还有其它的例子
```typescript
## 4.2 Boolean类型
boolean类型由true和false两个逻辑值组成。
通常在条件语句中使用boolean类型的变量:
```typescript
let isDone: boolean = false;
// ...
if (isDone) {
console.log ('Done!');
}
4.3 String 类型
string代表字符序列;可以使用转义字符来表示字符。
字符串字面量由单引号(')或双引号(")之间括起来的零个或多个字符组成。字符串字面量还有一特殊形式,是用反向单引号(`)括起来的模板字面量。
let s1