鸿蒙开发文档
序列
01、HarmonyOS基础技能
01、一切从Hello World开始
01、快速入门
02、开发基础知识
02、ArkTS语言
03、ArkTS语言介绍
02、ArkTS语法练习
04、ArkTS基础知识思维导图
05、ArkTS语言思维导图
06、ArkTS编程规范
07、HarmonyOS术语
02、鸿蒙博客
03、进阶
01、应用框架
本文档使用 MrDoc 发布
-
+
首页
05、ArkTS语言思维导图
```mindmap # ArkTS - 基本知识 - 声明 - 类型 - 运算符 - 语句 - 函数 - 函数声明 - 函数声明 - function add(x: string, y: string): string { let z: string = `${x} ${y}`; return z; } - 可选参数 - 可选参数的格式可为name?: Type - 可选参数的另一种形式为设置的参数默认值 - Rest参数 - 函数的最后一个参数可以是rest参数 - est参数的格式为...restArgs - function sum(...numbers: number[]): number { } - 返回类型 - 显式指定返回类型:function foo(): string { return 'foo'; } - 推断返回类型为string:function goo() { return 'goo'; } - 不需要返回值的函数的返回类型可以显式指定为void或省略标注 - 函数的作用域 - 函数中定义的变量和其他实例仅可以在函数内部访问,不能从外部访问 - 如果函数中定义的变量与外部作用域中已有实例同名,则函数内的局部变量定义将覆盖外部定义 - 函数调用 - 函数类型 - 函数类型通常用于定义回调 - 例如:type trigFunc = (x: number) => number; function do_action(f: trigFunc) { f(3.141592653589); // 调用函数 } do_action(Math.sin); // 将函数作为参数传入 - 箭头函数(Lambda函数) - 箭头函数的返回类型可以省略;省略时,返回类型通过函数体推断 - 例子: let sum = (x: number, y: number): number => { return x + y; } - let sum1 = (x: number, y: number) => { return x + y; } - let sum2 = (x: number, y: number) => x + y - 闭包 - 闭包是由函数及声明该函数的环境组合而成的 - 定义函数,返回值为函数 - 例子: function f(): () => number { let count = 0; let g = (): number => { count++; return count; }; return g; } let z = f(); z(); // 返回:1 z(); // 返回:2 - 函数重载 - 为同一个函数写入多个同名但签名不同的函数头,函数实现紧随其后 - function foo(x: number): void; /* 第一个函数定义 */ - function foo(x: string): void; /* 第二个函数定义 */ - function foo(x: number | string): void { /* 函数实现 */ } - 不允许重载函数有相同的名字以及参数列表,否则将会编译报错 - 类 - 类声明 - 类声明引入一个新类型,并定义其字段、方法和构造函数。 - 例子 class Person { name: string = ''; surname: string = ''; constructor (n: string, sn: string) { this.name = n; this.surname = sn; } fullName(): string { return this.name + ' ' + this.surname; } } - 定义类后,可以使用关键字new创建实例:let p = new Person('John', 'Smith'); - 或者,可以使用对象字面量创建实例:let p: Point = {x: 42, y: 42}; - 字段 - 实例字段:在构造函数时将字段初始化值;let p1 = new Person('Alice', 25); - 静态字段 - 使用关键字static将字段声明为静态 - 静态字段属于类本身,类的所有实例共享一个静态字段 - 要访问静态字段,需要使用类名:Person.numberOfPersons; - 字段初始化 - name: string = ''; setName(n:string): void { this.name = n; } // 类型为'string',不可能为"null"或者"undefined" getName(): string { return this.name; } - getter和setter - 字段 - setter和getter可用于提供对对象属性的受控访问。 - 例子 class Person { name: string = ''; private _age: number = 0; get age(): number { return this._age; } set age(x: number) { if (x < 0) { throw Error('Invalid age argument'); } this._age = x; } } let p = new Person(); p.age; // 输出0 p.age = -42; // 设置无效age值会抛出错误 - 方法 - 实例方法 - 实例方法既可以访问静态字段,也可以访问实例字段,包括类的私有字段 - 方法例子: class RectangleSize { calculateArea(): number { return 0; } } let square = new RectangleSize(10, 10); square.calculateArea(); // 输出:100 - 静态方法 - 使用关键字static将方法声明为静态。静态方法属于类本身,只能访问静态字段 - 静态方法定义了类作为一个整体的公共行为 - 例子: class Cl { static staticMethod(): string { return 'this is a static method.'; } } console.log(Cl.staticMethod()); - 继承 - 一个类可以继承另一个类(称为基类),并使用以下语法实现多个接口 - 格式: class [extends BaseClassName] [implements listOfInterfaces] { // ...} - 继承类例子 class Employee extends Person { salary: number = 0; calculateTaxes(): number { return this.salary * 0.42; } } - 继承接口例子 interface DateInterface { now(): string; } class MyDate implements DateInterface { now(): string { // 在此实现 return 'now'; } } - 父类访问 - 关键字super可用于访问父类的实例字段、实例方法和构造函数 - 方法重写 - 子类可以重写其父类中定义的方法的实现 - 重写的方法必须具有与原始方法相同的参数类型和相同或派生的返回类型。 - 方法重载签名 - 为同一个方法写入多个同名但签名不同的方法头,方法实现紧随其后 - class C { foo(x: number): void; /* 第一个签名 */ foo(x: string): void; /* 第二个签名 */ foo(x: number | string): void { /* 实现签名 */ } } let c = new C(); c.foo(123); // OK,使用第一个签名 c.foo('aa'); // OK,使用第二个签名 - 构造函数 - 类声明可以包含用于初始化对象状态的构造函数。 - 如果未定义构造函数,则会自动创建具有空参数列表的默认构造函数。 - constructor ([parameters]) { // ...} - 派生类的构造函数 - 造函数函数体的第一条语句可以使用关键字super来显式调用直接父类的构造函数 - constructor(side: number) { super(side, side); } - 构造函数重载签名 - 通过编写重载签名,指定构造函数的不同调用方式 - 为同一个构造函数写入多个同名但签名不同的构造函数头,构造函数实现紧随其后 - 如果两个重载签名的名称和参数列表均相同,则为错误。 - class C { constructor(x: number) /* 第一个签名 */ constructor(x: string) /* 第二个签名 */ constructor(x: number | string) { /* 实现签名 */ } } let c1 = new C(123); // OK,使用第一个签名 let c2 = new C('abc'); // OK,使用第二个签名 - 可见性修饰符 - 可见性修饰符包括:private、protected和public。默认可见性为public。 - 对象字面量 - 对象字面量是一个表达式,可用于创建类实例并提供一些初始值 - 在某些情况下更方便,可以用来代替new表达式 - 表示方式是:封闭在花括号对({})中的'属性名:值'的列表 - let c: C = {n: 42, s: 'foo'}; - Record类型的对象字面量 - 泛型Record<K, V>用于将类型(键类型)的属性映射到另一个类型(值类型 - 类型K可以是字符串类型或数值类型,而V可以是任何类型 - let map: Record<string, number> = { 'John': 25, 'Mary': 21, } map['John']; // 25 - 抽象类 - 带有修饰符abstract的类称为抽象类 - 象类可用于表示一组更具体的概念所共有的概念 - abstract class X { }; - 抽象类的子类可以是抽象类也可以是非抽象类 - 抽象父类的非抽象子类可以实例化 - 抽象方法 - 带有abstract修饰符的方法称为抽象方法:abstract method(p: string) - 抽象方法可以被声明但不能被实现 - 只有抽象类内才能有抽象方法,如果非抽象类具有抽象方法,则会发生编译时错误 - 接口 - 接口声明 - 类以关键字interface 开头:interface Style { color: string; // 属性} - 任何一个类的实例只要实现了特定接口,就可以通过该接口实现多态 - 接口通常包含属性和方法的声明 - 接口属性 - 接口属性可以是字段、getter、setter或getter和setter组合的形式 - 属性字段只是getter/setter对的便捷写法。以下表达方式是等价的 - interface Style { color: string;} - interface Style { get color(): string; set color(x: string);} - 接口继承 - 接口可以继承其他接口 - 继承接口包含被继承接口的所有属性和方法,还可以添加自己的属性和方法 - 抽象类和接口 - 抽象类与接口都无法实例化 - 象类是类的抽象,抽象类用来捕捉子类的通用特性,接口是行为的抽象 - 区别 - 一个类只能继承一个抽象类,而一个类可以实现一个或多个接口 - 接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法 - 抽象类里面可以有方法的实现,但是接口完全都是抽象的,不存在方法的实现; - 抽象类可以有构造函数,而接口不能有构造函数。 - 泛型类型和函数 - 泛型类和接口 - 类和接口可以定义为泛型,将参数添加到类型定义中 - class CustomStack<Element> { public push(e: Element):void { // ... } } - let s = new CustomStack<string>(); s.push('hello'); - 泛型约束 - 类型参数可以被限制只能取某些特定的值。例如,MyHashMap<Key, Value>这个类中的Key类型参数必须具有hash方法 - 例如:class MyHashMap<Key extends Hashable, Value> { } - 泛型约束 - 泛型函数 - function last<T>(x: T[]): T { return x[x.length - 1]; } - 泛型默认值 - 泛型类型的类型参数可以设置默认值 - interface Interface <T1=SomeType> { } - class Base <T2=SomeType> { } - 空安全 - 空安全 - 默认情况下,ArkTS中的所有类型都是不可为空的,因此类型的值不能为空 - let x: number = null; // 编译时错误 - let x: number | null = null; // 编译正常 - 非空断言运算符 - 后缀运算符!可用于断言其操作数为非空。 - a.value; // 编译时错误:无法访问可空值的属性 - a!.value; // 编译通过,如果运行时a的值非空,可以访问到a的属性;如果运行时a的值为空,则发生运行时异常 - 空值合并运算符 - 空值合并二元运算符??用于检查左侧表达式的求值是否等于null或者undefined - a ?? b等价于三元运算符(a != null && a != undefined) ? a : b - 可选链 - 在访问对象属性时,如果该属性是undefined或者null,可选链运算符会返回undefined。 - getSpouseNick(): string | null | undefined { return this.spouse?.nick; } - getSpouseNick的返回类型必须为string | null | undefined,因为该方法可能返回null或者undefined。 - 可选链可以任意长,可以包含任意数量的?.运算符。 - 模块 - 模块 - 程序可划分为多组编译单元或模块 - 每个模块都有其自己的作用域,即,在模块中创建的任何声明(变量、函数、类等)在该模块之外都不可见,除非它们被显式导出 - 与此相对,从另一个模块导出的变量、函数、类、接口等必须首先导入到模块中 - 导出 - 可以使用关键字export导出顶层的声明 - 未导出的声明名称被视为私有名称,只能在声明该名称的模块中使用 - 例子 - export class Point { } - export let Origin = new Point(0, 0); - export function Distance(p1: Point, p2: Point): number { } - 导入 - 静态导入 - 导入声明用于导入从其他模块导出的实体,并在当前模块中提供其绑定 - 导入声明由两部分组成 - 导入路径,用于指定导入的模块 - 导入绑定,用于定义导入的模块中的可用实体集和使用形式(限定或不限定使用) - 导入绑定可以有几种形式 - 导入绑定* as A表示绑定名称“A”,通过A.name可访问从导入路径指定的模块导出的所有实体 import * as Utils from './utils'; Utils.X // 表示来自Utils的X Utils.Y // 表示来自Utils的Y - 导入绑定{ ident1, ..., identN }表示将导出的实体与指定名称绑定,该名称可以用作简单名称 import { X, Y } from './utils'; X // 表示来自utils的X Y // 表示来自utils的Y - 如果标识符列表定义了ident as alias,则实体ident将绑定在名称alias下 import { X as Z, Y } from './utils'; Z // 表示来自Utils的X Y // 表示来自Utils的Y X // 编译时错误:'X'不可见 - 动态导入 - 应用开发的有些场景中,如果希望根据条件导入模块 或者按需导入模块,可以使用动态导入代替静态导入。 - import()语法通常称为动态导入(dynamic import), 是一种类似函数的表达式,用来动态导入模块。以这种方式调用,将返回一个promise。 - 例子 - import(modulePath)可以加载模块并返回一个promise,该promise resolve为一个包含其所有导出的模块对象 // Calc.ts export function add(a:number, b:number):number { let c = a + b; console.info('Dynamic import, %d + %d = %d', a, b, c); return c; } ############################## // Index.ts import("./Calc").then((obj: ESObject) => { console.info(obj.add(3, 5)); }).catch((err: Error) => { console.error("Module dynamic import error: ", err); }); - 异步函数中,可以使用let module = await import(modulePath) // say.ts export function hi() { console.log('Hello'); } export function bye() { console.log('Bye'); } ############################## async function test() { let ns = await import('./say'); let hi = ns.hi; let bye = ns.bye; hi(); bye(); } - 导入HarmonyOS SDK的开放能力 - HarmonyOS SDK提供的开放能力(接口)也需要在导入声明后使用 - 通过导入Kit方式使用开放能力有三种方式 - 导入Kit下单个模块的接口能力。例如:import { UIAbility } from '@kit.AbilityKit'; - 导入Kit下多个模块的接口能力。例如:import { UIAbility, Ability, Context } from '@kit.AbilityKit'; - 导入Kit包含的所有模块的接口能力。例如:import * as module from '@kit.AbilityKit'; - 方式三可能会导入过多无需使用的模块,导致编译后的HAP包太大,占用过多资源,请谨慎使用。 - 顶层语句 - 顶层语句是指在模块的最外层直接编写的语句,这些语句不被包裹在任何函数、类、块级作用域中 - 顶层语句包括变量声明、函数声明、表达式等 - 关键字 - this - 关键字this只能在类的实例方法中使用 - class A { count: string = 'a'; m(i: string): void { this.count = i; } } - 使用限制: - 不支持this类型 - 不支持在函数和类的静态方法中使用this - 关键字this的指向: - 调用实例方法的对象 - 正在构造的对象 ```
个人天使
2025年4月28日 16:35
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
PDF文档(打印)
分享
链接
类型
密码
更新密码