第三章 ArkTS语言基础(上):语法概览、变量声明与类型系统、函数定义与高阶函数
好,咱们开始进入ArkTS语言基础部分。说实话,很多同学一上来就急着写界面、调接口,结果代码写得乱七八糟,后面维护起来想哭。我个人习惯是,先把语言基础打扎实,后面写代码就像搭积木一样顺畅。
ArkTS是鸿蒙应用开发的主力语言。它基于TypeScript,但针对鸿蒙系统做了不少优化。说白了,你如果会TypeScript,上手ArkTS会很快。但如果你只会JavaScript,嗯,有几个坑我得提前给你指出来。
3.1 ArkTS语法概览
先看一个最简单的ArkTS程序长什么样:
@Entry
@Component
struct HelloWorld {
build() {
Column() {
Text('Hello, HarmonyOS!')
.fontSize(30)
.fontColor(Color.Blue)
}
.padding(20)
}
}
看到没?结构很清晰。@Entry和@Component是装饰器,告诉系统这是个页面组件。build()方法里写UI布局。ArkTS的语法风格偏向声明式,你描述“要什么”,而不是“怎么画”。
3.2 变量声明与类型系统
变量声明这块,ArkTS和TypeScript基本一致。但有几个细节我得强调一下。
3.2.1 let、const 与 var
在ArkTS中,我建议你只用let和const。var虽然能用,但它的作用域规则容易出问题。你想想看,一个变量在函数里声明了,结果在函数外还能访问到,这多吓人?
// 推荐写法
let count: number = 0
const appName: string = '车载导航'
// 不推荐
var oldWay = '别这么写'
const声明的是常量,一旦赋值就不能再改。但要注意,如果常量是对象,对象内部的属性还是可以改的。嗯,这里是个小坑。
3.2.2 类型系统
ArkTS是强类型语言。这意味着每个变量都有明确的类型。为什么要强类型?说白了,就是让编译器帮你提前发现错误。我在项目里见过太多因为类型不匹配导致的运行时崩溃了。
基础类型包括:
| 类型 | 说明 | 示例 |
|---|---|---|
| number | 数字,包括整数和浮点数 | let age: number = 25 |
| string | 字符串 | let name: string = '车载' |
| boolean | 布尔值 | let isRunning: boolean = true |
| undefined | 未定义 | let x: undefined = undefined |
| null | 空值 | let y: null = null |
还有更复杂的类型,比如数组、对象、联合类型等。举个例子:
// 数组
let list: number[] = [1, 2, 3]
let list2: Array<string> = ['a', 'b', 'c']
// 对象类型
interface CarInfo {
brand: string
speed: number
isElectric: boolean
}
let myCar: CarInfo = {
brand: '鸿蒙汽车',
speed: 120,
isElectric: true
}
// 联合类型
let id: number | string = 'ABC123'
3.2.3 类型推断
ArkTS也能自动推断类型。比如:
let message = 'Hello' // 自动推断为 string 类型
let count = 42 // 自动推断为 number 类型
但我不建议过度依赖类型推断。特别是函数返回值,显式标注类型能让代码更清晰。我曾经接手过一个项目,函数返回值全靠猜,那叫一个痛苦。
3.3 函数定义与高阶函数
函数是代码组织的基本单元。ArkTS的函数定义方式很灵活,咱们一个一个看。
3.3.1 函数定义
最基本的函数定义:
// 普通函数
function add(a: number, b: number): number {
return a + b
}
// 箭头函数
const multiply = (x: number, y: number): number => {
return x * y
}
// 可选参数
function greet(name: string, greeting?: string): string {
if (greeting) {
return `${greeting}, ${name}!`
}
return `Hello, ${name}!`
}
// 默认参数
function createCar(brand: string, speed: number = 100): void {
console.log(`创建了一辆${brand},速度${speed}km/h`)
}
注意那个?:语法,表示参数是可选的。调用时可以不传。默认参数就更方便了,不传就用默认值。
3.3.2 高阶函数
高阶函数,说白了就是“函数里面用函数”。要么接收函数作为参数,要么返回一个函数。这个概念在ArkTS里非常常用。
举个例子,车载应用里经常要处理列表数据:
// 高阶函数:map
const speeds: number[] = [60, 80, 100, 120]
const speedLimits = speeds.map(s => s * 1.1) // 每个速度增加10%
console.log(speedLimits) // [66, 88, 110, 132]
// 高阶函数:filter
const fastCars = speeds.filter(s => s > 80)
console.log(fastCars) // [100, 120]
// 高阶函数:reduce
const totalSpeed = speeds.reduce((acc, cur) => acc + cur, 0)
console.log(totalSpeed) // 360
你想想看,如果没有高阶函数,你得写多少循环?代码又长又容易出错。高阶函数让数据处理变得优雅。
0就是初始值。
3.3.3 自定义高阶函数
你也可以自己写高阶函数。比如车载系统里经常要记录操作日志:
// 自定义高阶函数:日志装饰器
function withLogging(fn: Function): Function {
return function(...args: any[]) {
console.log(`调用函数:${fn.name},参数:`, args)
const result = fn(...args)
console.log(`函数返回:`, result)
return result
}
}
// 使用
function calculateDistance(speed: number, time: number): number {
return speed * time
}
const loggedCalculate = withLogging(calculateDistance)
loggedCalculate(60, 2) // 会打印日志
这个模式在鸿蒙开发里很实用。比如你想给所有按钮点击事件加上埋点,用高阶函数包装一下就行,不用每个按钮都写一遍埋点代码。
3.4 实际项目中的经验
最后分享几个我在车载项目里踩过的坑:
- 类型断言要谨慎:有时候你觉得某个变量肯定是某个类型,就用
as断言。但运行时如果类型不对,程序直接崩溃。能用类型守卫就用类型守卫。 - 箭头函数的this:箭头函数不绑定自己的this,它会捕获外层上下文的this。这在回调函数里特别有用。但如果你用普通函数,this可能会指向undefined。
- 函数重载:ArkTS支持函数重载,但写法有点特殊。同一个函数名,写多个类型签名,最后写实现。我建议新手先别碰这个,容易搞混。
好了,这一章的内容就到这里。ArkTS的语法基础是后面所有内容的地基。你把这些概念吃透了,后面写UI组件、处理状态管理、调用系统API,都会顺手很多。下一章咱们继续深入,聊聊ArkTS的面向对象编程和模块化。