3、ArkTS语言基础(上):ArkTS语法概览、变量声明与数据类型、函数定义与箭头函数、类与接口的基本使用
3.1 ArkTS语法概览:从JavaScript到ArkTS的进化
说实话,第一次接触ArkTS的时候,我心想:「这不就是TypeScript换了个马甲吗?」
后来真在鸿蒙项目里写起来,才发现没那么简单。ArkTS是华为基于TypeScript做的一套静态类型语言,专门为鸿蒙的声明式UI框架服务。它砍掉了JS里那些动态类型的「野路子」,强制你写得更规范。
我个人习惯把ArkTS看作是「带镣铐跳舞」——限制多了,但代码质量确实上去了。你想想看,在团队协作中,类型不匹配导致的bug能少一大半。
3.2 变量声明与数据类型:别再写「let a = 1」了
嗯,这里要注意。在ArkTS里,变量声明必须带上类型注解。我见过不少从JS转过来的新手,上来就写let count = 0,然后编译器直接报错。
正确的写法是这样的:
// 基础数据类型
let count: number = 0
let name: string = '鸿蒙开发'
let isReady: boolean = true
let data: null = null
let value: undefined = undefined
// 数组类型
let list: number[] = [1, 2, 3]
let names: Array<string> = ['Alice', 'Bob']
// 联合类型
let id: number | string = 100
id = 'A001' // 这样也可以
// 类型推断(偷懒写法)
let age = 25 // 编译器自动推断为number类型
我曾经在项目里犯过一个低级错误:把一个接口返回的status字段声明成了number,结果后端某天改成了字符串"200",整个页面白屏。从那以后,我对联合类型特别敏感——let status: number | string,稳得很。
3.3 函数定义与箭头函数:两种写法,一个灵魂
ArkTS里的函数,说白了就两种写法:普通函数和箭头函数。但它们的区别,很多人搞不清楚。
先看普通函数:
// 普通函数声明
function add(a: number, b: number): number {
return a + b
}
// 函数表达式
const multiply = function(a: number, b: number): number {
return a * b
}
再看箭头函数:
// 箭头函数
const subtract = (a: number, b: number): number => {
return a - b
}
// 单行表达式可以省略return和大括号
const double = (x: number): number => x * 2
// 无参数箭头函数
const greet = (): string => 'Hello ArkTS'
为什么会有箭头函数?我记得刚学JS那会儿,被this指向搞得晕头转向。普通函数里的this是调用时决定的,而箭头函数里的this是定义时决定的。在鸿蒙的UI回调里,箭头函数能避免很多this丢失的问题。
this指向了全局对象,数据怎么都更新不了。换成箭头函数,问题秒解。记住:在ArkTS的UI回调中,优先使用箭头函数。
3.4 类与接口的基本使用:面向对象,但别过度设计
类在ArkTS里用得挺多的,尤其是定义数据模型和业务逻辑。接口则更像是一份「契约」,规定你的类必须长什么样。
先看接口:
// 定义接口
interface User {
id: number
name: string
age?: number // 可选属性
readonly createdAt: Date // 只读属性
}
// 实现接口
function printUser(user: User): void {
console.log(`用户${user.name}的ID是${user.id}`)
}
// 使用
const user: User = {
id: 1,
name: '张三',
createdAt: new Date()
}
printUser(user)
再看类:
// 定义类
class Person {
// 属性声明
private name: string
protected age: number
public readonly id: number
// 构造函数
constructor(name: string, age: number) {
this.name = name
this.age = age
this.id = Math.floor(Math.random() * 1000)
}
// 方法
public sayHello(): string {
return `你好,我是${this.name}`
}
// getter/setter
get personName(): string {
return this.name
}
set personName(newName: string) {
if (newName.length > 0) {
this.name = newName
}
}
}
// 继承
class Student extends Person {
private grade: number
constructor(name: string, age: number, grade: number) {
super(name, age) // 调用父类构造函数
this.grade = grade
}
// 重写方法
public sayHello(): string {
return `${super.sayHello()},我在${this.grade}年级`
}
}
// 使用
const student = new Student('李四', 18, 12)
console.log(student.sayHello())
我个人习惯是:接口定义数据结构,类定义行为逻辑。别把类写得跟接口一样全是属性没有方法,那还不如直接用对象字面量。
3.5 实战小技巧:类型守卫与可选链
最后分享两个我在项目中常用的技巧。
类型守卫: 当你用联合类型时,需要判断具体是哪种类型。
function processValue(value: string | number): void {
if (typeof value === 'string') {
console.log(value.toUpperCase())
} else {
console.log(value.toFixed(2))
}
}
可选链: 避免访问深层嵌套对象时报错。
// 假设有个深层对象
const response = {
data: {
user: {
address: {
city: '北京'
}
}
}
}
// 传统写法(容易报错)
// const city = response.data.user.address.city
// 可选链写法(安全)
const city = response?.data?.user?.address?.city ?? '未知'
console.log(city) // 输出:北京
嗯,这些基础语法看着简单,但真写起来容易踩坑。我建议你每学一个知识点,都打开DevEco Studio敲一遍。代码这东西,光看是学不会的。