ZetCode

TypeScript 迭代器

最后修改时间:2025年3月3日

TypeScript 中的迭代器提供了一种遍历数组、Map 和 Set 等集合的方式。它们实现了 IterableIterator 协议,支持自定义迭代逻辑。本教程将探讨迭代器、生成器和实际示例。

基本迭代器协议

迭代器必须实现 next() 方法,该方法返回一个具有 valuedone 属性的对象。此示例展示了一个简单的迭代器。

basic_iterator.ts
const numbers = [1, 2, 3];
const iterator = numbers[Symbol.iterator]();

console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: undefined, done: true }

Symbol.iterator 方法返回一个迭代器对象。next() 方法推进迭代器并返回当前值。

自定义迭代器

您可以通过实现 Iterable 接口来创建自定义迭代器。此示例定义了一个自定义范围迭代器。

custom_iterator.ts
class Range implements Iterable<number> {
    constructor(private start: number, private end: number) {}

    [Symbol.iterator](): Iterator<number> {
        let current = this.start;
        return {
            next: () => {
                return current <= this.end
                    ? { value: current++, done: false }
                    : { value: undefined, done: true };
            }
        };
    }
}

const range = new Range(1, 3);
for (const num of range) {
    console.log(num); // Output: 1, 2, 3
}

Range 类实现了 Iterable 接口。Symbol.iterator 方法返回一个迭代器对象。

生成器

生成器使用 function* 语法简化了迭代器的创建。它们自动实现迭代器协议。

generator.ts
function* generateSequence(start: number, end: number) {
    for (let i = start; i <= end; i++) {
        yield i;
    }
}

const sequence = generateSequence(1, 3);
for (const num of sequence) {
    console.log(num); // Output: 1, 2, 3
}

yield 关键字会暂停执行并返回值。生成器非常适合惰性求值。

遍历 Map

Map 默认是可迭代的。此示例演示了如何遍历 Map 的键、值和条目。

map_iterator.ts
const map = new Map([
    ['a', 1],
    ['b', 2],
    ['c', 3]
]);

for (const [key, value] of map) {
    console.log(`${key}: ${value}`); // Output: a: 1, b: 2, c: 3
}

Map 提供了键、值和条目的内置迭代器。使用解构来访问键值对。

遍历 Set

Set 也是可迭代的。此示例展示了如何遍历 Set 的值。

set_iterator.ts
const set = new Set([1, 2, 3]);

for (const value of set) {
    console.log(value); // Output: 1, 2, 3
}

Set 存储唯一值并提供简单的迭代器进行遍历。

异步迭代器

异步迭代器支持异步数据遍历。此示例使用异步生成器来获取数据。

async_iterator.ts
async function* fetchData(urls: string[]) {
    for (const url of urls) {
        const response = await fetch(url);
        yield response.json();
    }
}

(async () => {
    const urls = ['https://api.example.com/data1', 'https://api.example.com/data2'];
    for await (const data of fetchData(urls)) {
        console.log(data);
    }
})();

异步迭代器使用 for await...of 来处理异步数据流。它们对于 API 和数据库很有用。

组合迭代器

您可以使用实用函数组合多个迭代器。此示例将两个数组合并到一个迭代器中。

combine_iterators.ts
function* mergeIterators<T>(...iterators: Iterable<T>[]) {
    for (const iterator of iterators) {
        yield* iterator;
    }
}

const merged = mergeIterators([1, 2], [3, 4]);
for (const num of merged) {
    console.log(num); // Output: 1, 2, 3, 4
}

yield* 关键字将迭代委托给另一个可迭代对象。这种模式对于组合数据源很有用。

最佳实践

来源

TypeScript 迭代器文档

本教程通过实际示例涵盖了 TypeScript 迭代器。使用这些模式来高效处理集合和异步数据。

作者

我叫 Jan Bodnar,我是一名热情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。至今,我已撰写了 1,400 多篇文章和 8 本电子书。我在教授编程方面拥有十多年的经验。

列出所有 TypeScript 教程