TypeScript 迭代器
迭代器(Iterator)提供统一的方式逐个访问集合中的元素。在 TypeScript 中,实现了 Symbol.iterator 方法的对象称为"可迭代对象",可直接用 for...of 遍历;生成器(Generator)则是用函数语法快速制造迭代器的利器。
1. 可迭代协议
对象只要提供 Symbol.iterator 方法并返回一个迭代器,就能被 for...of 消费。迭代器必须带 next() 方法,每次返回 { value, done }:
interface IterResult<T> {
value: T;
done: boolean;
}
interface MyIterator<T> {
next(): IterResult<T>;
}
2. 内置可迭代对象
数组、字符串、Map、Set 都是可迭代对象,可以直接 for...of 或展开:
const arr: number[] = [1, 2, 3];
for (const n of arr) console.log(n); // 输出:1 / 2 / 3
const s = new Set(["a", "b"]);
for (const x of s) console.log(x); // 输出:a / b
console.log([...arr]); // 输出:[1, 2, 3]
3. 自定义迭代器
普通对象实现 Symbol.iterator 后即可自定义遍历顺序,例如"从 1 数到 3":
const counter = {
[Symbol.iterator](): MyIterator<number> {
let i = 0;
return {
next: () => ({ value: ++i, done: i > 3 }),
};
},
};
for (const n of counter) console.log(n); // 输出:1 / 2 / 3
4. 生成器函数 function*
生成器函数用 function* 声明,执行到 yield 时暂停并吐出一个值,下次调用 next() 再继续:
function* genNums(): Generator<number> {
yield 1;
yield 2;
yield 3;
}
for (const n of genNums()) console.log(n); // 输出:1 / 2 / 3
5. 生成器实战:无限序列
生成器可以表达"无限"的数据流而不占用内存,配合手动 next() 按需取值:
function* fibonacci(): Generator<number> {
let a = 0;
let b = 1;
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
const it = fibonacci();
console.log(it.next().value); // 输出:0
console.log(it.next().value); // 输出:1
console.log(it.next().value); // 输出:1
小结
迭代器是 for...of 与展开运算符的底层协议:需要自定义遍历顺序时实现 Symbol.iterator,需要惰性生成数据序列时用 function* 配合 yield,生成器返回值本身就是可迭代对象。