第四章 ArkTS语言基础(下):循环语句、函数定义与调用、箭头函数、高阶函数、闭包与作用域

好,咱们接着往下聊。上一章我们把 ArkTS 的基础类型和条件判断捋了一遍,这一章要上点强度了——循环、函数、还有那些让新手头疼的闭包和作用域。别怕,我尽量用大白话讲明白。

一、循环语句:让代码学会“重复劳动”

写代码最烦什么?重复写差不多的逻辑。循环就是干这个的。ArkTS 里常用的循环有三种:forfor...ofwhile

1. 传统 for 循环

最基础的那种,适合你知道要循环多少次的情况。

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

我个人习惯在遍历数组索引时用这个,因为可以灵活控制步长。比如跳着取元素:

let arr = [10, 20, 30, 40, 50];
for (let i = 0; i < arr.length; i += 2) {
    console.log(arr[i]); // 输出 10, 30, 50
}

2. for...of 循环

这个就优雅多了。直接拿元素,不用管索引。我项目中处理列表数据时,90% 的场景都用它。

let fruits = ['苹果', '香蕉', '橘子'];
for (let fruit of fruits) {
    console.log(fruit);
}
小提示:如果你既想要索引又想要值,可以用 entries() 方法。比如 for (let [index, fruit] of fruits.entries()),这样两个都能拿到。

3. while 循环

适合你不知道具体循环次数,只知道什么时候停的场景。比如等待某个条件成立。

let count = 0;
while (count < 3) {
    console.log('等待中...');
    count++;
}
注意:写 while 循环一定要记得更新条件变量,不然就死循环了。我曾经在调试一个网络重连逻辑时,忘了加计数器,结果程序直接卡死,手机发烫得能煎鸡蛋。

二、函数定义与调用:把逻辑“打包”起来

函数说白了就是把一段逻辑装进一个盒子里,起个名字,想用的时候叫它一声。

1. 函数声明

function greet(name: string): string {
    return '你好,' + name;
}

调用很简单:greet('小明')。这里 : string 是返回值类型,ArkTS 推荐都写上,方便别人读你的代码。

2. 可选参数与默认参数

有时候参数不是必须的。用 ? 标记:

function logMessage(msg: string, level?: string): void {
    console.log(`[${level ?? 'INFO'}] ${msg}`);
}

或者直接给默认值:

function multiply(a: number, b: number = 1): number {
    return a * b;
}

嗯,这里要注意:可选参数必须放在必选参数后面,不然编译器会报错。

三、箭头函数:更简洁的写法

箭头函数是 ES6 带来的好东西,ArkTS 也支持。写法更短,而且不绑定自己的 this

// 传统写法
let add = function(a: number, b: number): number {
    return a + b;
};

// 箭头函数写法
let add = (a: number, b: number): number => a + b;

如果函数体只有一行,连 return 和花括号都能省。我刚开始用的时候觉得这写法太“偷懒”了,后来真香——尤其是写回调函数的时候。

核心区别:箭头函数没有自己的 this,它会捕获定义时所在上下文的 this。这在事件处理、定时器里特别有用,不会出现 this 指向丢失的问题。

四、高阶函数:函数也能当参数

什么叫高阶函数?就是函数可以接收另一个函数作为参数,或者返回一个函数。说白了,函数在 ArkTS 里是一等公民,可以像变量一样传来传去。

function processArray(arr: number[], fn: (item: number) => number): number[] {
    let result: number[] = [];
    for (let item of arr) {
        result.push(fn(item));
    }
    return result;
}

let doubled = processArray([1, 2, 3], (x) => x * 2);
console.log(doubled); // [2, 4, 6]

你看,processArray 接收一个函数 fn,然后对每个元素应用这个函数。这就是高阶函数的典型用法。ArkTS 内置的 mapfilterreduce 都是高阶函数。

实战经验:我在做列表筛选功能时,经常用 filter 配合箭头函数,一行代码搞定。比如 let adults = users.filter(u => u.age >= 18);,简洁又清晰。

五、闭包与作用域:理解“变量去哪儿了”

闭包这个概念,很多新手觉得玄乎。其实说白了就是:一个函数能记住它定义时的环境,即使这个函数在别的地方被调用。

1. 作用域基础

ArkTS 的作用域分三种:全局作用域、函数作用域、块级作用域(用 letconst 声明的变量)。

let globalVar = '我是全局的';

function test() {
    let funcVar = '我是函数内的';
    if (true) {
        let blockVar = '我是块级的';
        console.log(blockVar); // 可以访问
    }
    // console.log(blockVar); // 报错!块级变量外面访问不到
}

2. 闭包的实际例子

function createCounter() {
    let count = 0;
    return function() {
        count++;
        return count;
    };
}

let counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3

为什么 count 没有被销毁?因为返回的那个匿名函数一直“记住”了它。这就是闭包。

避坑指南:我曾经在循环里创建闭包,结果所有闭包都共享了同一个变量值。比如 for (var i = 0; i < 5; i++) 里创建闭包,最后所有闭包拿到的 i 都是 5。解决方案?用 let 代替 var,或者用立即执行函数包裹一下。

六、知识体系总览

下面这张图把本章的核心知识点串起来了,方便你复习时一眼看清脉络。

ArkTS 语言基础(下) 循环语句 for / for...of / while 函数定义与调用 声明 / 参数 / 返回值 箭头函数 简洁语法 / 无 this 绑定 高阶函数 函数作参数 / 返回值 闭包与作用域 闭包:函数 + 定义时的环境 作用域:全局 / 函数 / 块级 💡 实践建议 多用 for...of 遍历数组,用箭头函数写回调 注意闭包中的变量引用,避免循环陷阱

七、总结一下

这一章的内容,说白了就是让你学会“让代码自己重复干活”(循环)、“把逻辑打包复用”(函数)、“写更简洁的回调”(箭头函数)、“把函数当数据传来传去”(高阶函数),以及“理解变量为什么能记住”(闭包与作用域)。

我个人觉得,闭包是这里面最值得花时间琢磨的。你想想看,很多高级用法——比如防抖、节流、柯里化——底层都是闭包。搞懂了它,后面学框架会轻松很多。

好,这一章就到这儿。代码多敲几遍,尤其是闭包那个计数器例子,自己改改试试。下次见。


专注资料整理