鸿蒙开发文档
序列
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 发布
-
+
首页
03、ArkTS语言介绍
>i > > 为构建高性能应用而设计的语言 >在继承TypeScript语法的基础上进行了优化,以提供更高的性能和开发效率 >一大特性:专注于低运行时开销, >d **变量声明** > > 以关键字let开头的声明引入变量,该变量在程序执行期间可以具有不同的值 > ``` > let hi: string = 'hello'; hi = 'hello, world'; > ``` >w **常量声明** > > 以关键字const开头的声明引入只读常量,该常量只能被赋值一次 >``` > const hello: string = 'hello'; >``` >s **自动类型推断** > > 一个变量或常量的声明包含了初始值,那么开发者就不需要显式指定其类型 >``` >let hi1: string = 'hello'; let hi2 = 'hello, world'; >``` ## 类型 >i **number类型** > > 任何整数和浮点数都可以被赋给此类型的变量 >数字字面量包括整数字面量和十进制浮点数字面量 >整数字面量包括以下类别: >> * 由数字序列组成的十进制整数。例如:0、117、-345 >> * 以0x(或0X)开头的十六进制整数,可以包含数字(0-9)和字母a-f或A-F。例如:0x1123、0x00111、-0xF1A7 >> * 以0o(或0O)开头的八进制整数,只能包含数字(0-7)。例如:0o777 >> * 以0b(或0B)开头的二进制整数,只能包含数字0和1。例如:0b11、0b0011、-0b11 > >浮点字面量包括以下 >> *十进制整数,可为有符号数(即,前缀为“+”或“-”); >> * 小数点(“.”) >> * 小数部分(由十进制数字字符串表示) >> * 以“e”或“E”开头的指数部分,后跟有符号(即,前缀为“+”或“-”)或无符号整数。 > > number类型在表示大整数时会造成精度丢失。在开发时可以按需使用bigInt类型来确保精度: > ``` >let bigIntger: BigInt = BigInt('999999999999999999999999999999999999999999999999999999999999'); console.log('bigIntger' + bigIntger.toString()); > ``` >d **boolean类型** > > boolean类型由true和false两个逻辑值组成 >``` >let isDone: boolean = false; >// ... >if (isDone) { > console.log ('Done!'); >} >``` >w **string类型** > > string代表字符序列;可以使用转义字符来表示字符 >字符串字面量由单引号(')或双引号(")之间括起来的零个或多个字符组成。 >字符串字面量还有一特殊形式,是用反向单引号(`)括起来的模板字面量 >``` >let s1 = 'Hello, world!\n'; >let s2 = 'this is a string'; >let a = 'Success'; >let s3 = `The result is ${a}`; >``` >s **void类型** > > void类型用于指定函数没有返回值 >由于void是引用类型,因此它可以用于泛型类型参数 >``` >class Class<T> { > //... >} >let instance: Class <void> >``` >i **Object类型** > > Object类型是所有引用类型的基类型。 >任何值,包括基本类型的值(它们会被自动装箱),都可以直接被赋给Object类型的变量。 >object类型则用于表示除基本类型外的类型。 >d **array类型** > > 即数组,是由可赋值给数组声明中指定的元素类型的数据组成的对象 >数组可由数组复合字面量(即用方括号括起来的零个或多个表达式的列表,其中每个表达式为数组中的一个元素)来赋值。 >数组的长度由数组中元素的个数来确定。数组中第一个元素的索引为0。 > ``` >let names: string[] = ['Alice', 'Bob', 'Carol']; > ``` >w **enum类型** > > enum类型,又称枚举类型,是预先定义的一组命名值的值类型,其中命名值又称为枚举常量 >使用枚举常量时必须以枚举类型名称为前缀 >``` >enum ColorSet { Red, Green, Blue } let c: ColorSet = ColorSet.Red; >``` >常量表达式可以用于显式设置枚举常量的值 >``` >enum ColorSet { White = 0xFF, Grey = 0x7F, Black = 0x00 } let c: ColorSet = ColorSet.Black; >``` >s **Union类型** > > union类型,即联合类型,是由多个类型组合成的引用类型。联合类型包含了变量可能的所有类型 >``` >class Cat { > name: string = 'cat'; > // ... >} >class Dog { > name: string = 'dog'; > // ... >} >class Frog { > name: string = 'frog'; > // ... >} >type Animal = Cat | Dog | Frog | number; >// Cat、Dog、Frog是一些类型(类或接口) > >let animal: Animal = new Cat(); >animal = new Frog(); >animal = 42; >// 可以将类型为联合类型的变量赋值为任何组成类型的有效值 >``` >可以用不同的机制获取联合类型中特定类型的值。 >``` >class Cat { sleep () {}; meow () {} } >class Dog { sleep () {}; bark () {} } >class Frog { sleep () {}; leap () {} } > >type Animal = Cat | Dog | Frog; > >function foo(animal: Animal) { > if (animal instanceof Frog) { > animal.leap(); // animal在这里是Frog类型 > } > animal.sleep(); // Animal具有sleep方法 >} >``` >i **Aliases类型** > > Aliases类型为匿名类型(数组、函数、对象字面量或联合类型)提供名称,或为已有类型提供替代名称。 >``` >type Matrix = number[][]; type Handler = (s: string, no: number) => string; type Predicate <T> = (x: T) => boolean; type NullableObject = Object | null; >``` ## 运算符 >d **赋值运算符** > > 赋值运算符=,使用方式如x=y >复合赋值运算符将赋值与运算符组合在一起,其中x op = y等于x = x op y >复合赋值运算符列举如下:+=、-=、*=、/=、%=、<<=、>>=、>>>=、&=、|=、^=。 >i **比较运算符** > > ``` === 如果两个操作数严格相等(对于不同类型的操作数认为是不相等的),则返回true。 !== 如果两个操作数严格不相等(对于不同类型的操作数认为是不相等的),则返回true。 == 如果两个操作数相等,则返回true。 != 如果两个操作数不相等,则返回true。 > 如果左操作数大于右操作数,则返回true。 >= 如果左操作数大于或等于右操作数,则返回true。 < 如果左操作数小于右操作数,则返回true。 <= 如果左操作数小于或等于右操作数,则返回true。 >i **算术运算符** > > 一元运算符为-、+、--、++ >二元运算符 >``` + 加法 - 减法 * 乘法 / 除法 % 除法后余数 >s **位运算符** > > 这是一个成功提示文本 > ``` a & b 按位与:如果两个操作数的对应位都为1,则将这个位设置为1,否则设置为0。 a | b 按位或:如果两个操作数的相应位中至少有一个为1,则将这个位设置为1,否则设置为0。 a ^ b 按位异或:如果两个操作数的对应位不同,则将这个位设置为1,否则设置为0。 ~ a 按位非:反转操作数的位。 a << b 左移:将a的二进制表示向左移b位。 a >> b 算术右移:将a的二进制表示向右移b位,带符号扩展。 a >>> b 逻辑右移:将a的二进制表示向右移b位,左边补0。 >i **逻辑运算符** > > ``` a && b 逻辑与 a || b 逻辑或 ! a 逻辑非 ## 语句 >s **If语句** > > 1. else部分也可能包含if语句 > ``` if (condition1) { // 语句1 } else if (condition2) { // 语句2 } else { // else语句 } > > > 2. 条件表达式可以是任何类型。但是对于boolean以外的类型,会进行隐式类型转换 >d **Switch语句** > > 使用switch语句来执行与switch表达式值匹配的代码块 如果switch表达式的值等于某个label的值,则执行相应的语句 如果没有任何一个label值与表达式值相匹配,并且switch具有default子句,那么程序会执行default子句对应的代码块。 break语句(可选的)允许跳出switch语句并继续执行switch语句之后的语句。 如果没有break语句,则执行switch中的下一个label对应的代码块。 >``` switch (expression) { case label1: // 如果label1匹配,则执行 // ... // 语句1 // ... break; // 可省略 case label2: case label3: // 如果label2或label3匹配,则执行 // ... // 语句23 // ... break; // 可省略 default: // 默认语句 } >i **条件表达式** > > 条件表达式由第一个表达式的布尔值来决定返回其它两个表达式中的哪一个 >``` >condition ? expression1 : expression2 >``` >如果condition的值为真值(转换后为true的值),则使用expression1作为该表达式的结果;否则,使用expression2。 >``` >let message = Math.random() > 0.5 ? 'Valid' : 'Failed'; >w **警告提示** > > for语句会被重复执行,直到循环退出语句值为false >``` >for ([init]; [condition]; [update]) { statements } >``` >``` >let sum = 0; for (let i = 0; i < 10; i += 2) { sum += i; } >s **For-of语句** > > 使用for-of语句可遍历数组或字符串。 >``` for (forVar of expression) { statements } >``` >``` for (let ch of 'a string object') { /* process ch */ } >i **While语句** > > 只要condition为真值(转换后为true的值),while语句就会执行statements语句 >``` >while (condition) { statements } >``` >``` >let n = 0; let x = 0; while (n < 3) { n++; x += n; } >d **Do-while语句** > > 如果condition的值为真值(转换后为true的值),那么statements语句会重复执行 >``` >do { statements } while (condition) >``` >``` >let i = 0; do { i += 1; } while (i < 10) >w **Break语句** > > 使用break语句可以终止循环语句或switch。 >``` >let x = 0; while (true) { x++; if (x > 5) { break; } } >``` >如果break语句后带有标识符,则将控制流转移到该标识符所包含的语句块之外。 >``` >let x = 1; label: while (true) { switch (x) { case 1: // statements break label; // 中断while语句 } } >s **Continue语句** > > continue语句会停止当前循环迭代的执行,并将控制传递给下一个迭代 > ``` > let sum = 0; for (let x = 0; x < 100; x++) { if (x % 2 == 0) { continue; } sum += x; } >i **Throw和Try语句** > >``` throw语句用于抛出异常或错误: >throw new Error('this error') >``` >``` try语句用于捕获和处理异常或错误 >try { // 可能发生异常的语句块 } catch (e) { // 异常处理 } > ``` 下面的示例中throw和try语句用于处理除数为0的错误 class ZeroDivisor extends Error {} function divide (a: number, b: number): number{ if (b == 0) throw new ZeroDivisor(); return a / b; } function process (a: number, b: number) { try { let res = divide(a, b); console.log('result: ' + res); } catch (x) { console.log('some error'); } } ``` ``` 支持finally语句 function processData(s: string) { let error: Error | null = null; try { console.log('Data processed: ' + s); // ... // 可能发生异常的语句 // ... } catch (e) { error = e as Error; // ... // 异常处理 // ... } finally { if (error != null) { console.log(`Error caught: input='${s}', message='${error.message}'`); } } } ``` ## 函数 >i **函数声明** > > 函数声明引入一个函数,包含其名称、参数列表、返回类型和函数体 >在函数声明中,必须为每个参数标记类型。如果参数为可选参数,那么允许在调用函数时省略该参数。函数的最后一个参数可以是rest参数 >``` 以下示例是一个简单的函数,包含两个string类型的参数,返回类型为string >function add(x: string, y: string): string { let z: string = `${x} ${y}`; return z; } >d **可选参数** > > 可选参数的格式可为name?: Type。 >``` >function hello(name?: string) { if (name == undefined) { console.log('Hello!'); } else { console.log(`Hello, ${name}!`); } } >``` >可选参数的另一种形式为设置的参数默认值。如果在函数调用中这个参数被省略了,则会使用此参数的默认值作为实参。 >``` >function multiply(n: number, coeff: number = 2): number { return n * coeff; } multiply(2); // 返回2*2 multiply(2, 3); // 返回2*3 >i **Rest参数** > > 函数的最后一个参数可以是rest参数。rest参数的格式为...restArgs。rest参数允许函数接收一个由剩余实参组成的数组,用于处理不定数量的参数输入。 >``` >function sum(...numbers: number[]): number { let res = 0; for (let n of numbers) res += n; return res; } > >sum(); // 返回0 sum(1, 2, 3); // 返回6 >i **返回类型** > > ``` 如果可以从函数体内推断出函数返回类型,则可在函数声明中省略标注返回类型 > // 显式指定返回类型 function foo(): string { return 'foo'; } > >// 推断返回类型为string function goo() { return 'goo'; } >``` > 不需要返回值的函数的返回类型可以显式指定为void或省略标注。这类函数不需要返回语句。 >``` >function hi1() { console.log('hi'); } function hi2(): void { console.log('hi'); } >i **函数的作用域** > > 函数中定义的变量和其他实例仅可以在函数内部访问,不能从外部访问 >如果函数中定义的变量与外部作用域中已有实例同名,则函数内的局部变量定义将覆盖外部定义 >i **函数调用** > > 调用函数以执行其函数体,实参值会赋值给函数的形参 >``` >function join(x: string, y: string): string { let z: string = `${x} ${y}`; return z; } // 则此函数的调用需要包含两个string类型的参数: let x = join('hello', 'world'); console.log(x); >i **函数类型** > >``` 数类型通常用于定义回调 >type trigFunc = (x: number) => number // 这是一个函数类型 > >function do_action(f: trigFunc) { f(3.141592653589); // 调用函数 } > >do_action(Math.sin); // 将函数作为参数传入 >i **箭头函数(又名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 >i **闭包** > > 闭包是由函数及声明该函数的环境组合而成的。该环境包含了这个闭包创建时作用域内的任何局部变量。 >在下例中,f函数返回了一个闭包,它捕获了count变量,每次调用z,count的值会被保留并递增 >``` function f(): () => number { let count = 0; let g = (): number => { count++; return count; }; return g; } > >let z = f(); z(); // 返回:1 z(); // 返回:2 >i **函数重载** > > 我们可以通过编写重载,指定函数的不同调用方式。具体方法为,为同一个函数写入多个同名但签名不同的函数头,函数实现紧随其后 >``` function foo(x: number): void; /* 第一个函数定义 */ function foo(x: string): void; /* 第二个函数定义 */ function foo(x: number | string): void { /* 函数实现 */ } > >foo(123); // OK,使用第一个定义 foo('aa'); // OK,使用第二个定义 // 不允许重载函数有相同的名字以及参数列表,否则将会编译报错 >i **类** > > 类声明引入一个新类型,并定义其字段、方法和构造函数。 >在以下示例中,定义了Person类,该类具有字段name和surname、构造函数和方法fullName: >``` 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'); console.log(p.fullName()); >``` >``` 或者,可以使用对象字面量创建实例: >class Point { x: number = 0; y: number = 0; } let p: Point = {x: 42, y: 42}; >i **字段** > > 字段是直接在类中声明的某种类型的变量。 类可以具有实例字段或者静态字段 >i **实例字段** > > 实例字段存在于类的每个实例上。每个实例都有自己的实例字段集合。 要访问实例字段,需要使用类的实例。 >``` >class Person { name: string = ''; age: number = 0; constructor(n: string, a: number) { this.name = n; this.age = a; } > > getName(): string { return this.name; } } > >let p1 = new Person('Alice', 25); p1.name; let p2 = new Person('Bob', 28); p2.getName(); >i **静态字段** > > 使用关键字static将字段声明为静态。静态字段属于类本身,类的所有实例共享一个静态字段 >``` 要访问静态字段,需要使用类名 >class Person { static numberOfPersons = 0; constructor() { // ... Person.numberOfPersons++; // ... } } > >Person.numberOfPersons;
个人天使
2025年3月5日 17:19
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
PDF文档(打印)
分享
链接
类型
密码
更新密码