第3章 ArkTS语言基础(上):认识ArkTS

好,咱们开始进入ArkTS的世界。

说实话,我第一次接触ArkTS的时候,心里也犯嘀咕——这不就是TypeScript换了个马甲吗?但真正上手写了一个页面之后,我发现事情没那么简单。ArkTS确实是基于TypeScript的,但它针对鸿蒙的声明式UI做了大量优化。说白了,它就是让你用更少的代码,写出更流畅的界面。

3.1 什么是ArkTS?

ArkTS是鸿蒙原生应用的主力开发语言。它继承了TypeScript的静态类型检查,又加上了声明式UI的写法。你想想看,以前写界面,你得手动创建组件、设置属性、添加到父容器……一套流程下来,代码又长又乱。现在呢?直接描述界面长什么样就行。

我个人习惯把ArkTS理解为「带UI能力的TypeScript」。它保留了TS的类型系统,但把UI部分做成了声明式的。举个例子:

@Entry
@Component
struct HelloPage {
  build() {
    Column() {
      Text('你好,鸿蒙')
        .fontSize(30)
        .fontColor(Color.Blue)
    }
    .width('100%')
    .height('100%')
  }
}

看到没?没有繁琐的创建过程,直接写TextColumn,然后链式调用设置样式。这就是声明式UI的魅力。

核心要点:ArkTS = TypeScript + 声明式UI + 鸿蒙原生能力。它不是一门新语言,而是TS在鸿蒙上的最佳实践。

3.2 基本数据类型

ArkTS的数据类型和TypeScript基本一致。我刚开始学的时候,觉得这部分太简单了,结果在项目里踩了个坑——number类型在ArkTS里默认是双精度浮点数,如果你做金融计算,精度会出问题。嗯,这里要注意。

3.2.1 常用类型

类型 说明 示例
number 数字(整数和浮点数) let age: number = 25
string 字符串 let name: string = '张三'
boolean 布尔值 let isOk: boolean = true
null 空值 let a: null = null
undefined 未定义 let b: undefined = undefined

我在项目中遇到过一个问题:从后端接口拿到的数据,有时候是null,有时候是undefined。如果不做判断直接使用,页面就会白屏。所以后来我养成了一个习惯——所有可能为空的数据,都用??操作符给个默认值。

let userName: string | null = getUserName()
let displayName: string = userName ?? '默认用户'

3.2.2 联合类型与类型推断

ArkTS支持联合类型,就是让一个变量可以是多种类型。比如:

let id: number | string
id = 123    // 没问题
id = 'abc'  // 也没问题

不过我个人建议,能明确类型就尽量明确。类型推断虽然方便,但有时候会推断出any,那就失去类型检查的意义了。

小技巧:在ArkTS里,如果你不确定一个变量的类型,可以用typeof运算符在运行时检查。比如typeof id === 'string'

3.3 变量声明:let、const 和 var

这部分其实和TypeScript一模一样。但我还是要啰嗦一句:尽量用const,少用let,别用var

为什么?var有变量提升的问题,容易造成作用域混乱。我曾经在写一个循环的时候,用var声明了循环变量,结果循环结束后这个变量还在,导致后面的逻辑出了bug。从那以后,我再也没用过var

// 推荐写法
const PI = 3.14159
let count = 0

// 不推荐
var oldWay = '别用我'

你想想看,const声明的是常量,一旦赋值就不能改。这能帮你避免很多意外修改。而let是块级作用域,只在当前大括号内有效,比var安全得多。

3.4 条件语句

条件判断是写逻辑的基础。ArkTS里最常用的就是if...elseswitch

3.4.1 if...else

let score: number = 85
if (score >= 90) {
  console.log('优秀')
} else if (score >= 60) {
  console.log('及格')
} else {
  console.log('不及格')
}

这里有个坑:ArkTS对类型检查很严格。比如if (score)这种写法,如果score0,会被当作false处理。所以最好写成if (score !== null && score !== undefined),或者用??操作符。

注意:在ArkTS的UI组件里,条件渲染要用if,不能用v-ifngIf。比如:

if (this.isVisible) {
  Text('显示我')
}

3.4.2 switch 语句

当判断条件比较多的时候,switchif...else更清晰。不过要注意,每个case后面要加break,不然会穿透执行。

let day: number = 3
switch (day) {
  case 1:
    console.log('周一')
    break
  case 2:
    console.log('周二')
    break
  case 3:
    console.log('周三')
    break
  default:
    console.log('其他')
}

我曾经在项目里忘写break,结果case 1执行完直接跑到case 2去了,排查了半天才发现。嗯,这种低级错误,犯过一次就记住了。

3.5 循环语句

循环在ArkTS里主要有三种:forfor...ofwhile

3.5.1 for 循环

最传统的写法,适合知道循环次数的情况:

for (let i = 0; i < 5; i++) {
  console.log('第' + i + '次循环')
}

3.5.2 for...of 循环

这个我特别喜欢,专门用来遍历数组或集合。代码简洁,不容易出错:

let fruits: string[] = ['苹果', '香蕉', '橘子']
for (let fruit of fruits) {
  console.log(fruit)
}

你想想看,如果用传统的for循环,你得写fruits[i],还得小心数组越界。用for...of就省心多了。

3.5.3 while 循环

适合条件不确定的情况:

let count: number = 0
while (count < 3) {
  console.log('计数:' + count)
  count++
}

不过要小心死循环。我刚开始学的时候,有一次忘了写count++,结果程序卡死了。所以用while的时候,一定要确保循环条件会变化。

实战建议:在ArkTS的UI开发中,循环经常用来渲染列表。比如用ForEach组件:

ForEach(this.itemList, (item: string) => {
  Text(item)
})

这个后面章节会详细讲,先有个印象就好。

3.6 避坑指南

最后,我把自己在ArkTS基础部分踩过的坑总结一下:

  • 类型不匹配:ArkTS对类型要求很严格,numberstring不能直接拼接。比如let a: number = 5 + '5'会报错。要用String(5) + '5'或者5 + Number('5')
  • 变量提升:别用var,用letconst。这是血的教训。
  • 循环中的异步问题:for循环里用async/await要小心,for...of可以正确处理异步,但forEach不行。
  • 条件渲染的括号:在UI组件里用if,一定要加大括号。比如if (condition) { Text('内容') },少了大括号会报错。

好了,这一章的内容就到这里。ArkTS的基础语法其实不难,关键是养成好习惯。下一章咱们会深入函数和面向对象,到时候你会看到ArkTS更强大的一面。