第四章 ArkTS语言基础(下):循环语句、函数定义与调用、箭头函数、高阶函数、闭包与作用域
好,咱们接着往下聊。上一章我们把 ArkTS 的基础类型和条件判断捋了一遍,这一章要上点强度了——循环、函数、还有那些让新手头疼的闭包和作用域。别怕,我尽量用大白话讲明白。
一、循环语句:让代码学会“重复劳动”
写代码最烦什么?重复写差不多的逻辑。循环就是干这个的。ArkTS 里常用的循环有三种:for、for...of 和 while。
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++;
}
二、函数定义与调用:把逻辑“打包”起来
函数说白了就是把一段逻辑装进一个盒子里,起个名字,想用的时候叫它一声。
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 内置的 map、filter、reduce 都是高阶函数。
filter 配合箭头函数,一行代码搞定。比如 let adults = users.filter(u => u.age >= 18);,简洁又清晰。
五、闭包与作用域:理解“变量去哪儿了”
闭包这个概念,很多新手觉得玄乎。其实说白了就是:一个函数能记住它定义时的环境,即使这个函数在别的地方被调用。
1. 作用域基础
ArkTS 的作用域分三种:全局作用域、函数作用域、块级作用域(用 let 和 const 声明的变量)。
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,或者用立即执行函数包裹一下。
六、知识体系总览
下面这张图把本章的核心知识点串起来了,方便你复习时一眼看清脉络。
七、总结一下
这一章的内容,说白了就是让你学会“让代码自己重复干活”(循环)、“把逻辑打包复用”(函数)、“写更简洁的回调”(箭头函数)、“把函数当数据传来传去”(高阶函数),以及“理解变量为什么能记住”(闭包与作用域)。
我个人觉得,闭包是这里面最值得花时间琢磨的。你想想看,很多高级用法——比如防抖、节流、柯里化——底层都是闭包。搞懂了它,后面学框架会轻松很多。
好,这一章就到这儿。代码多敲几遍,尤其是闭包那个计数器例子,自己改改试试。下次见。