End

鸿蒙 ArkTS 基础语法

本文地址


目录

鸿蒙 ArkTS 基础语法

官方文档

类型

以关键字let声明引入变量,以关键字const声明引入只读常量

let hi: string = 'hello';
const hello: string = 'hello';

ArkTS提供numberNumber类型,任何整数和浮点数都可以被赋给此类型的变量。

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模式一样。

settergetter 可用于提供对对象属性的受控访问。

属性字段只是 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

posted @ 2024-11-03 01:34  白乾涛  阅读(34)  评论(0编辑  收藏  举报