什么是 ArkTS

ArkTS 是鸿蒙生态的应用开发语言,它提供了声明式 UI 范式、状态管理支持等相应的能力,让开发者可以以更简洁、更自然的方式开发应用。

同时,它在保持 Typescript(简称 TS)基本语法风格的基础上,进一步通过规范强化静态检査和分析,使得在程序运行之前的开发期能检测更多错误,提升代码正确性;并实现更好的运行性能。

ArkTS 发展趋势

  1. 保持 TypeScript 基础语法风格,规范强化静态检查和分析,提升程序稳定性,实现更好的运行性能
  2. 拓展了对 UI 的支持,提供了 UI 声明式描述和状态管理的语法
  3. 持续演进,拓展现代语言特性

ArkTS 的定位及约束

  1. ArkTS 作为 OH/HMOS 官方主流推荐开发语言
  2. .ets 以及 .d.ets 作为 ArkTS 语言源码后缀
  3. 与 TS/JS 高效互操作,兼容 TS/JS 生态
  4. ets 文件可以 import ets/ts/js 文件源码,但是 ts/js 文件不允许 import ets 文件源码
  5. 新增 SDK API(不包括NDK部分)接口需要符合 ArkTS 规范

ArkTS 基于 TypeScript 的增强

更多对比标准 TS 的差异访问:https://developer.huawei.com/consumer/cn/arkts/

ArkTS 对 UI 的扩展

  1. UI 描述:
    ArkTS 在 TS 的类型系统的基础上,做了进一步的扩展:定义了各种装饰器、自定义组件和UI 描述机制,再配合 UI 开发框架中的 UI 内置组件、事件方法、属性方法等共同构成了应用开发的主体。

  2. 状态管理:
    UI 相关联的数据,不仅可以在组件内使用,还可以在不同组件层级间传递,比如父子组件之间,爷孙组件之间,也可以是全局范围内的传递,还可以是跨设备传递。

ArkTS 基础语法

声明

ArkTS 中可以通过关键字 let 声明变量,使用 const 声明一个常量,并通过类型注释指定类型。

1
2
3
let count: number = 10; //变量声明
count = 40;
const MAX_COUNT: number = 100; //常量声明

类型

  1. 基本类型:string 、number 、boolean、Enum
1
2
3
4
5
6
7
8
let name: string='小明';
let age: number= 20;
let isMale: boolean = true,
console.log(name);//输出小明
console.log(age.tostring());//输出20
console.log(`我的名字叫${name},今年${age}岁`);
enum Color {Red,Blue,Green}
let favouriteColor: Color = Color.Red;
  1. 应用类型:Array、基于 Ojbect 的自定义类
1
2
let students: Array<string>= ['小明','小张','小王','小李'];
let students: string[]= ['小明','小张','小王','小李'];
  1. 联合类型:Union
1
2
let luckyNum:number|string = 7;
luckyNum = 'seven';
  1. 类型别名:Aliases
1
2
type Matrix= number[];
type Nullableobject = object | null;

语句

  1. 条件语句:用于基于不同的条件来执行不同的动作,根据判断条件的执行结果(true 或 false)来决定执行的代码块。
1
2
3
4
5
6
let isValid: boolean;
if (Math.random()>0.5) {
isValid = true;
} else {
isValid = false;
}

条件表达式 let isValid = Math.random() > 0.5 ? true : false;

  1. 循环语句:用于重复执行相同的一组语句,提高效率、简化代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let students: string[] = ['小明', '小张', '小王', '小李'];
//for 循环
for (let i = 0; i < students.length; i++) {
console.log(students[i]);
}
//for of 循环
for (let student of students) {
console.log(student);
}
//while 循环
let index = 0;
while (index < students.length) {
console.log(students[index]);
index++;
}

函数

函数是一组一起执行多条语句的组合,形成可重用的代码块。通过 function 关键字声明要告诉编译器函数的名称、返回类型和参数以及执行的内容。

1
2
3
4
5
6
7
function printStudentsInfo(students: string[]): void {
for (let student of students) {
console.log(student);
}
}
printStudentInfo(['小明', '张三', '小李'])
printStudentInfo(['小敏', '小黄', '小陈', '小刘'])

箭头函数/lambda表达式:通常用于需要一个简单函数的地方,并且在其他地方不会被重复使用。箭头函数的返回类型可以省略,省略时,返回类型通过函数体推断,执行体只有一行的情况下可以省略花括号。

1
2
const printInfo = (name: string) => console.log(name);
printInfo('小明');

表达更简短,常用于作为回调函数

1
2
let students: string[] = ['小明', '小张', '小王', '小李'];
students.forEach((student: string) => console.log(student))

闭包函数:一个函数可以将另一个函数当做返回值,保留对内部作用域的访问

1
2
3
4
5
6
7
8
9
10
function outerFunc(): () => string {
let count = 0
return (): string => {
count++;
return count.toString()
}
}
let invoker = outerFunc()
console.log(invoker()) //输出:1
console.log(invoker()) //输出:2

类的声明和使用

  1. 类的声明:ArkTS 支持基于类的面向对象的编程方式,定义类的关键字为 class,后面紧跟类名。类的声明描述了所创建的对象共同的属性和方法。
1
2
3
4
5
class Person {
name: string = '小明';
age: number = 20;
isMale: boolean = true;
}
  1. 类的创建
1
2
const person = new Person(); //new 实例创建
console.log(person.name); //输出:小明
1
2
const person: Person = { name: '小张', age: 29, isMale: true }; //字面量创建
console.log(person.name); //输出:小张

constructor 用于实例化时进行初始化操作

1
2
3
4
5
6
7
8
9
10
11
12
class Person {
name: string = '小明';
age: number = 20;
isMale: boolean = true;
constructor(name: string, age: number, isMale: boolean) {
this.name = name;
this.age = age;
this.isMale = isMale;
}
}
const person = new Person('小张', 32, false);
console.log(person.name); //输出:小张

类的方法:用于描述类的行为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Person {
name: string = '小明';
age: number = 20;
isMale: boolean = true;
constructor(name: string, age: number, isMale: boolean) {
this.name = name;
this.age = age;
this.isMale = isMale;
}
introduce() {
if (this.isMale) {
console.log(` ${this.name}是个男生,年龄是${this.age}岁`);
} else {
console.log(` ${this.name}是个女生,年龄是${this.age}岁`);
}
}
}
  1. 类的使用

封装:将数据隐藏起来,只对外部提供必要的接口来访问和操作数据,确保数据的一致性和安全性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Person {
public name: string = '小明';
private _age: number = 20; //可见性修饰符包括:private、protected和public。默认可见性为public
isMale: boolean = true;
... //省略构造器和方法内容
get age(): number {
return this._age;
}
set age(age:number) {
this._age = age;
}
}
const person: Person = new Person('小张', 28, true);
console.log(person.age.toString()) //实际访问的是get方法
console.log(person._age.toString()) //无法直接访问私有属性

继承:子类继承父类的特征和行为,使得子类具有父类相同的行为。ArkTS 中允许使用继承来扩展现有的类,对应的关键字为 extends

1
2
3
4
5
6
7
8
9
10
class Employee extends Person {
private _department: string;
constructor(name: string, age: number, isMale: boolean, department: string)
{
super(name, age, isMale);
this._department = department;
}
}
const employee: Employee = new Employee('小张', 28, true, 'xx公司');
employee.introduce(); //输出:小张是个男生,今年28岁

多态:子类继承父类,并可以重写父类方法,使不同的实例对象对同一行为有不同的表现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Employee extends Person {
department: string;
constructor(name: string, age: number, isMale: boolean, department: string) {
super(name, age, isMale);
this.department = department;
}
public introduce(): string {
super.introduce();
console.log(` 在${this.department}工作 `);
}
}
const person: Person = new Person('小张', 28, true);
person.introduce(); //输出:小张是个男生,今年20岁
const employee: Employee = new Employee('小张', 28, true, 'xx公司');
employee.introduce(); //输出:小张是个男生,今年20岁 在xx公司工作

模块的导入与导出

一个ArkTS文件的作用域是独立的,通过export导出一个文件的变量、函数、类等

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//Person.ets
export class Person {
name: string = ‘小明';
age: number = 20;
isMale: boolean = true;
... //省略构造器内容
introduce() {
if (this.isMale) {
console.log(` ${this.name}是个男生,年龄是${this.age}岁`);
} else {
console.log(` ${this.name}是个女生,年龄是${this.age}岁`);
}
}
}

通过 import 导入另一个文件的变量、函数、类等

1
2
3
4
// Page.ets
import { Person } from './Person';
const person = new Person('小张', 20, true);
person.introduce(); //输出:小张是个男生,年龄是28岁