鸿蒙 ArkTS 基础语法
目录
鸿蒙 ArkTS 基础语法
类型
以关键字let
声明引入变量,以关键字const
声明引入只读常量
let hi: string = 'hello';
const hello: string = 'hello';
ArkTS提供number
和Number
类型,任何整数和浮点数都可以被赋给此类型的变量。
string
代表字符序列;可以使用转义字符来表示字符。可以使用单引号'
或双引号"
或反引号。只有反引号支持字符串模板,
let s1 = 'Hello, world!\n';
let s2 = "Success";
let s3 = `s1: ${s1}`;
void
类型用于指定函数没有返回值。此类型只有一个值,同样是void。由于void是引用类型,因此它可以用于泛型类型参数。
class A <T> {}
let instance: A <void>
Object
类型是所有引用类型的基类型。任何值,包括基本类型的值(它们会被自动装箱),都可以直接被赋给Object类型的变量。
array
,即数组。
enum
,枚举类型,是预先定义的一组命名值的值类型,其中命名值又称为枚举常量。常量表达式可以用于显式设置枚举常量的值。
union
,即联合类型,是由多个类型组合成的引用类型。
type Animal = Cat | Dog | Frog | number;
let animal: Animal = new Cat();
animal = new Frog();
animal = 42;
if (animal instanceof Frog) {} // 判断具体是哪种类型
运算符
===
:如果两个操作数严格相等(类型也要相同),则返回true
==
:如果两个操作数相等,则返回true
语句
if
语句:条件表达式可以是任何类型。但是对于boolean以外的类型,会进行隐式类型转换
if ('Hello') {
console.log("Hello");
}
if (10086) {
console.log("Hello");
}
switch
语句:case、break、default
for
语句:使用for-of
语句可遍历数组或字符串
for (let i = 0; i < 10; i += 2) {}
for (let ch of 'a string object') {}
break
语句可以终止循环语句或switch。break label
语句可以将控制流转移到该标识符所包含的语句块之外。
异常处理:throw、try、catch、finally
throw new Error('this error')
函数
y 有默认值,z 为可选参数
function add(x: string, y: string = "-", z?: string): string {
return x + y + z
}
add("b") // "b-undefined"
add("b", "q") // "bqundefined"
add("b", "q", "t") // "bqt"
函数的最后一个参数可以是rest参数。
function sum(...numbers: number[]): number {}
sum();
sum(1);
sum(1, 2, 3);
函数类型
type XX = (x: number, y: number) => number // 函数类型
function do_action(f: XX) {
let result = f(2, 3); // 调用函数
console.log(result.toString())
}
do_action(Math.max); // 3
do_action(Math.min); // 2
do_action(Math.pow); // 8
箭头函数,又名Lambda函数
闭包。闭包是由函数及声明该函数的环境组合而成的。该环境包含了这个闭包创建时作用域内的任何局部变量。
function f(): () => number {
let count = 0;
let g = (): number => {
count++;
console.log(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 {} /* 函数实现 */
foo(123); // OK,使用第一个定义
foo('aa'); // OK,使用第二个定义
类
可以使用关键字 new 创建实例,也可以使用对象字面量创建实例
关键字this
只能在类的实例方法、构造方法中使用。 不支持 this 类型
class Person {
name: string = ''; // 实例字段,默认可见性为 public
private surname: string = ''; // 私有字段
static numberX = 0; // 静态字段,静态方法同理
constructor(n: string, sn: string) { // 构造函数
this.name = n;
this.surname = sn;
Person.numberX++;
}
fullName(): string { // 方法
return this.name + ' ' + this.surname;
}
}
let p1 = new Person("bat", "hh")
let p2 = {
n: "bqt",
sn: "hh"
}
ArkTS要求所有字段在声明时或者构造函数中显式初始化。这和标准TS中的strictPropertyInitialization
模式一样。
setter 和 getter 可用于提供对对象属性的受控访问。
属性字段只是 getter/setter对 的便捷写法。
class Person {
private _age: number = 0;
get age(): number { return this._age; }
set age(x: number) {
this._age = x < 0 ? 0 : x;
}
}
let p1 = new Person()
p1.age = -1
console.log(p1.age)
继承与实现:extends、implements、protected、super、override
构造函数重载,和普通的函数重载语法一样
class C {
constructor(x: number) /* 第一个签名 */
constructor(x: string) /* 第二个签名 */
constructor(x: number | string) { /* 实现签名 */
}
}
let c1 = new C(123); // OK,使用第一个签名
let c2 = new C('abc'); // OK,使用第二个签名
接口
接口属性可以是字段、getter、setter或getter和setter组合的形式。
接口也可以继承其他接口。
interface X { }
interface Style extends X {
color: string // 属性
siez: number
someMethod(): void // 方法,返回值类型即使是 void 也不能省略
}
class A implements Style {
color: string = ''; // 重写属性的第一种方式
get siez(): number { return 1 };// 重写属性的第二种方式
set siez(x: number) { };
someMethod() { }
}
泛型
泛型类型的类型参数可以设置默认值。在泛型函数调用中,类型实参可以显式或隐式设置。
class Animal<T> { } // 泛型类和接口
let a = new Animal<string>();
class A { }
class B<K extends A, V = string> { name: K | undefined }
let b = new B<A, number>()
let c = new B<A>()
function last<T>(x: T[]): T {} // 泛型函数
last<number>([1, 2, 3]); // 显式设置的类型实参
last([1, 2, 3]); // 隐式设置的类型实参
泛型Record<K, V>
用于将类型(键类型)的属性映射到另一个类型(值类型)。常用对象字面量来初始化该类型的值。
类型K可以是字符串类型或数值类型,而V可以是任何类型。
let map: Record<string, number> = {
'John': 25,
'Mary': 21,
}
map['John']; // 25
空安全
默认情况下,ArkTS中的所有类型都是不可为空
的,因此类型的值不能为空。这类似于TypeScript的严格空值检查模式strictNullChecks
,但规则更严格。
let x: number = null; // 编译时错误
let y: string = null; // 编译时错误
let z: number[] = null; // 编译时错误
可以为允许空值的变量定义为联合类型 T | null
。
let x: number | null = null;
x = 1; // ok
x = null; // ok
if (x != null) {}
后缀运算符 !
可用于断言其操作数为非空。
function foo(a: A | null) {
a.value; // 编译时错误:无法访问可空值的属性
a!.value; // 编译通过,如果运行时a的值为空,则发生运行时异常
}
空值合并二元运算符 ??
a ?? b
等价于三元运算符 (a != null && a != undefined) ? a : b
。
在访问对象属性时,如果该属性是 undefined 或者 null,可选链运算符会返回 undefined。
// 返回类型必须为三者的联合类型,因为该方法可能返回 null 或者 undefined
getNick(): string | null | undefined {
return this.spouse?.nick;
}
模块导入导出
程序可划分为多组编译单元或模块。
顶层语句是指在模块的最外层直接编写的语句,这些语句不被包裹在任何函数、类、块级作用域中。顶层语句包括变量声明、函数声明、表达式等。
每个模块都有其自己的作用域,即,在模块中创建的任何声明(变量、函数、类等)在该模块之外都不可见,除非它们被显式导出。
导出。可以使用关键字 export 导出顶层的声明。未导出的声明名称被视为私有名称,只能在声明该名称的模块中使用。
export class Point {}
export let Origin = new Point(0, 0);
export function show(): number {}
静态导入。导入声明用于导入从其他模块导出的实体,并在当前模块中提供其绑定。
import * as Utils from './utils' // 导入绑定
Utils.X // 表示来自Utils的X
Utils.Y // 表示来自Utils的Y
import { X, Y } from './utils' // 将导出的实体与指定名称绑定
X // 表示来自utils的X
Y // 表示来自utils的Y
动态导入:根据条件导入模块或者按需导入模块
import('modulePath') // 加载模块,并返回一个包含其所有导出的模块对象
.then(obj => <module object>)
.catch(err => <loading error, e.g. if no such module>)
导入 HarmonyOS SDK
HarmonyOS SDK 提供的开放能力也需要在导入声明后使用。
SDK 对同一个 Kit 下的接口模块进行了封装,开发者在示例代码中可通过导入 Kit 的方式来使用 Kit 所包含的接口能力。其中,Kit 封装的接口模块可查看 SDK 目录下 Kit 子目录中各 Kit 的定义。
通过导入 Kit 方式使用开放能力有三种方式:
- 导入单个模块的接口能力:
import { UIAbility } from '@kit.AbilityKit';
- 导入多个模块的接口能力:
import { UIAbility, Ability, Context } from '@kit.AbilityKit';
- 导入所有模块的接口能力:
import * as xxx from '@kit.AbilityKit';
方式三可能会导入过多无需使用的模块,导致编译后的 HAP 包太大,占用过多资源,请谨慎使用。
2024.11.03
本文来自博客园,作者:白乾涛,转载请注明原文链接:https://www.cnblogs.com/baiqiantao/p/18522797