Appearance
ArkTS 基础语法
ArkTS 的语法核心:类型声明、let/const、函数、类、枚举、模块系统。
1. 类型声明与推导
1.1 显式类型声明
typescript
// 基础类型
let age: number = 25
let name: string = "小猫"
let isActive: boolean = true
let nothing: void = undefined
// 数组
let numbers: number[] = [1, 2, 3]
let names: Array<string> = ["a", "b", "c"]
// 元组
let person: [string, number] = ["小猫", 25]
// 对象字面量
let user: { name: string, age: number } = {
name: "小明",
age: 20
}
// 枚举
enum Direction { Up, Down, Left, Right }
let dir: Direction = Direction.Up // 值为 01.2 类型推导
typescript
// 编译器自动推导类型
let age = 25 // 推导为 number
let name = "小猫" // 推导为 string
let list = [1, 2] // 推导为 number[]
// 显式声明与推导混合
let config = {
width: 100, // number
height: 200, // number
visible: true, // boolean
items: [] as string[] // 需要 as 断言空数组类型
}1.3 never 类型
typescript
// never 表示永远不会返回的类型(死代码)
function error(msg: string): never {
throw new Error(msg)
}
// 在类型守卫中使用
function assertNever(x: never): never {
throw new Error(`Unexpected object: ${x}`)
}2. let 与 const(没有 var!)
2.1 块级作用域
typescript
// ArkTS 只有 let 和 const,没有 var
function test() {
if (true) {
let x = 1
const y = 2
console.log(x, y) // 1, 2
}
// console.log(x) // ❌ 编译错误!x 超出块级作用域
}
// var 不存在于 ArkTS,如果写了 var 会编译报错2.2 const 的使用
typescript
// 基础类型的 const
const PI: number = 3.14159
// 对象的 const 需要注意:对象引用不可变,但属性可变
const config = {
name: "app",
version: "1.0"
}
config.name = "newApp" // ✅ 允许(属性可变)
config = {} // ❌ 不允许(引用不可变)
// 使用 as const 使所有属性不可变
const CONST_CONFIG = {
name: "app",
version: "1.0"
} as const // 所有属性变为只读2.3 为什么没有 var?
- 变量提升(Hoisting):var 声明会被提升到函数顶部,容易引发 bug
- 作用域模糊:var 是函数作用域,不是块级作用域
- 静态分析:移除 var 让编译器能更准确地进行类型分析和内存优化
💡 面试考点:ArkTS 只有
const和let,没有var,因为var存在变量提升和作用域模糊的问题,不利于静态分析和内存优化。
3. 函数
3.1 函数声明
typescript
// 普通函数
function add(a: number, b: number): number {
return a + b
}
// 无返回值函数
function log(msg: string): void {
console.log(msg)
}
// 可选参数(必须放在最后)
function greet(name: string, greeting?: string): string {
return `${greeting ?? 'Hello'}, ${name}!`
}
// 默认参数
function greetWithDefault(name: string, greeting: string = 'Hello'): string {
return `${greeting}, ${name}!`
}3.2 箭头函数
typescript
// 箭头函数自动绑定 this(在 ArkTS 组件中非常重要!)
const double = (x: number): number => x * 2
// 组件中回调必须用箭头函数
@Component
struct MyComponent {
@State count: number = 0
// ✅ 正确:箭头函数绑定 this
onClick = (): void => {
this.count++ // this 指向当前组件实例
}
// ❌ 错误:普通函数 this 指向丢失
onClickWrong() {
this.count++ // this 可能为 undefined!
}
build() {
Button('点击')
.onClick(this.onClick)
}
}3.3 函数类型
typescript
// 函数类型声明
type MathFunc = (a: number, b: number) => number
const add: MathFunc = (a, b) => a + b
const multiply: MathFunc = (a, b) => a * b
// 高阶函数
function applyOperation(a: number, b: number, op: MathFunc): number {
return op(a, b)
}
// 回调类型
interface Callback {
(result: string, error?: string): void
}
function fetchData(cb: Callback): void {
cb('success')
}4. 类
4.1 基本类定义
typescript
class Person {
// 访问修饰符
public name: string // 公开
protected age: number // 子类可访问
private email: string // 仅类内访问
// 构造函数
constructor(name: string, age: number) {
this.name = name
this.age = age
}
// 普通方法
getAge(): number {
return this.age
}
// getter/setter
get email(): string {
return this.email
}
set email(value: string) {
this.email = value
}
}
const person = new Person("小明", 25)4.2 类的继承
typescript
class Animal {
protected name: string
constructor(name: string) {
this.name = name
}
speak(): string {
return `${this.name} makes a sound`
}
}
class Dog extends Animal {
private breed: string
constructor(name: string, breed: string) {
super(name) // 必须调用 super()
this.breed = breed
}
override speak(): string { // override 是可选的(但推荐)
return `${this.name} barks`
}
getBreed(): string {
return this.breed
}
}4.3 struct vs class 在 ArkTS 中的区别
| 特性 | struct(组件) | class(逻辑类) |
|---|---|---|
| 用途 | UI 组件 | 逻辑/数据模型 |
| 继承 | ❌ 不可继承 | ✅ 可继承 |
| 装饰器 | @Component | 无强制要求 |
| 必须有 build() | ✅ | ❌ |
| 实例化 | new MyStruct() | new MyClass() |
| 编译优化 | AOT 编译 | AOT 编译 |
💡 面试高频:自定义 UI 组件必须用
struct定义,不可继承;纯逻辑处理、数据模型类使用class。
5. 接口(Interface)
5.1 基本接口
typescript
// 定义对象结构
interface User {
name: string
age: number
email: string
isActive?: boolean // 可选属性
}
// 实现接口
function printUser(user: User): void {
console.log(user.name, user.age)
}
// 接口也可以用于函数签名
interface Calculator {
(a: number, b: number): number
}
const add: Calculator = (a, b) => a + b5.2 接口继承
typescript
// 接口支持 extends(多继承)
interface Person {
name: string
age: number
}
interface Employee extends Person {
id: string
department: string
salary: number
}
// 使用
const emp: Employee = {
name: "小明",
age: 28,
id: "E001",
department: "研发部",
salary: 20000
}5.3 接口 vs Type 别名
| 场景 | 推荐 | 原因 |
|---|---|---|
| 定义对象结构 | Interface | 支持合并(merge) |
| 联合类型 | Type | Interface 不支持联合 |
| 基本类型别名 | Type | 更简洁 |
| 元组类型 | Type | Interface 不支持 |
| 交叉类型 | Type | Interface 不支持 |
6. 枚举(Enum)
6.1 数字枚举
typescript
enum Status {
Idle = 0,
Loading = 1,
Success = 2,
Error = 3
}
// 反向映射
console.log(Status[0]) // "Idle"
console.log(Status.Success) // 26.2 字符串枚举
typescript
enum HttpMethod {
GET = "GET",
POST = "POST",
PUT = "PUT",
DELETE = "DELETE"
}
// 字符串枚举不支持反向映射(性能更好)6.3 常量枚举
typescript
// 编译时完全展开,无运行时开销
const enum Color {
Red = "RED",
Green = "GREEN",
Blue = "BLUE"
}
function draw(c: Color) {
// Color.Red 编译后变成 "RED"(零开销)
console.log(c)
}7. 模块系统
7.1 模块导出与导入
typescript
// utils/math.ts - 模块文件
export function add(a: number, b: number): number {
return a + b
}
export const PI: number = 3.14159
export default class Calculator {
multiply(a: number, b: number): number {
return a * b
}
}typescript
// pages/index.ts - 使用模块
import Calculator, { add, PI } from '../utils/math'
console.log(add(1, 2)) // 3
console.log(PI) // 3.14159
const calc = new Calculator()
console.log(calc.multiply(3, 4)) // 127.2 模块单例模式
typescript
// utils/singleTon.ts
class ApiService {
private static instance: ApiService
private constructor() {}
static getInstance(): ApiService {
if (!ApiService.instance) {
ApiService.instance = new ApiService()
}
return ApiService.instance
}
request(url: string): void {
// ...
}
}
export default ApiService.getInstance()typescript
// 在其他文件中使用
import api from '../utils/singleTon'
api.request('/api/data') // 全局唯一实例💡 面试技巧:鸿蒙中推荐用模块级导出实现单例。由于模块加载是单例的,
export default instance后该实例全局唯一,比手写单例模式更简洁可靠。
8. 类型断言
typescript
// as 断言(ArkTS 推荐)
const divEl = document.getElementById('container') as HTMLDivElement
// 空值断言(不推荐,应尽量避免)
let value: string | undefined = undefined
let str = value! // 告诉编译器"我知道这不为空"9. 面试高频考点
Q1: let/const 的区别?
回答:let 声明可变变量,const 声明不可变引用(对象属性仍可变)。ArkTS 没有 var。
Q2: struct vs class 的区别?
回答:UI 组件用 struct(不可继承,必须有 build()),逻辑类用 class(可继承,无 build() 限制)。
Q3: Interface vs Type?
回答:定义对象结构用 Interface(支持合并),联合类型/基本类型别名用 Type。
Q4: 箭头函数在 ArkTS 中的重要性?
回答:箭头函数自动绑定 this,在组件回调中防止 this 丢失,是 ArkTS 的必用语法。
🐱 小猫提示:基础语法部分面试主要考:类型系统、let/const、struct/class 区别、接口使用、箭头函数 this 绑定。每个点准备一个代码示例就能应付。