在 JavaScript 中,迭代器是一个非常强大的工具。它允许我们逐步遍历集合中的元素,如数组、字符串、Map 等。然而,除了使用内置的迭代器(如 for…of、Array.prototype.entries() 等),我们还可以手动实现自己的迭代器来满足特殊需求。今天我们就从零开始,逐步带你了解如何实现一个 JavaScript 迭代器。
一、什么是迭代器?
迭代器的本质是一个对象,它提供了一种标准化的访问数据的方法。它需要具备两个关键要素:
- next() 方法: 每次调用时,返回一个包含 value 和 done 属性的对象。
- 状态跟踪: 用于记录当前迭代的进度。
返回的对象结构为:
1 | { value: <当前值>, done: <是否结束> } |
- value 表示当前迭代项的值。
- done 是一个布尔值,用于表示迭代是否结束。
二、内置迭代器的简单例子
在继续之前,我们先来看一个数组的内置迭代器:
1 | const arr = [1, 2, 3]; |
这里我们使用了数组的内置 Symbol.iterator 方法。每次调用 next() 都会依次获取数组的下一个元素,直到所有元素遍历完成。
三、手动实现一个简单的迭代器
我们现在尝试手动实现一个基本的迭代器。目标是实现一个能遍历数组的自定义迭代器。
1 | function createArrayIterator(arr) { |
代码说明:
- createArrayIterator 函数接收一个数组作为参数。
- 每次调用 next(),都会返回当前数组元素并将索引前进一位。
- 当数组遍历完成后,返回 { value: undefined, done: true }。
四、为对象添加迭代器
我们可以通过 Symbol.iterator 为任何对象定义自定义的迭代逻辑。这样,我们的对象也能在 for…of 循环中使用。下面,我们为一个自定义对象实现迭代器。
1 | const range = { |
代码说明:
- range 对象表示一个范围,从 start 到 end。
- 在对象内部使用 Symbol.iterator 定义了一个迭代器。
- for…of 会自动调用对象的 Symbol.iterator 方法来获取迭代器。
五、实现无限迭代器
有时候,我们需要创建一个无限序列,比如生成斐波那契数列。下面是一个无限斐波那契迭代器的实现:
1 | function fibonacciIterator() { |
代码说明:
- 每次调用 next(),斐波那契序列都会前进一位,并返回当前的值。
- 无限序列的迭代器没有终止条件,因此 done 始终为 false。
六、可迭代对象与迭代器的区别
- 可迭代对象:具有 Symbol.iterator 方法的对象,可以在 for…of 中使用,如数组、字符串等。
- 迭代器:实现了 next() 方法的对象,每次调用 next() 返回一个 { value, done } 对象。
总结: 可迭代对象内部使用迭代器来实现元素的逐个访问。for…of 只是对迭代器的一种封装。