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,生成器返回值本身就是可迭代对象。

笔记加载中…