推荐答案
迭代器 (Iterator)
迭代器是一种对象,它允许你以某种方式遍历一个集合(例如数组、对象、Map、Set等)。它遵循特定的协议,主要包含一个 next()
方法。每次调用 next()
方法都会返回一个包含 value
和 done
属性的对象。value
代表当前迭代的值,done
是一个布尔值,表示迭代是否完成。当 done
为 true
时,表示迭代已经结束,不再有新的值。
-- -------------------- ---- ------- ----- ---------- - - ------ --- -- --- ------ -- ----- ---------- - -- ----------- - ------------------ - ------ - ------ ------------------------- ----- ----- -- - ---- - ------ - ------ ---------- ----- ---- -- - - -- ------------------------------- -- ------- -- ----- ------ ------------------------------- -- ------- -- ----- ------ ------------------------------- -- ------- -- ----- ------ ------------------------------- -- ------- ---------- ----- -----
生成器 (Generator)
生成器是一种特殊的函数,使用 function*
语法声明。生成器函数执行时不会立即运行,而是返回一个迭代器对象。生成器函数内部可以使用 yield
关键字来暂停执行,并返回一个值。每次调用迭代器的 next()
方法时,生成器函数会从上次 yield
处恢复执行,直到再次遇到 yield
或者函数结束。生成器可以创建无限序列,以及处理异步操作。
-- -------------------- ---- ------- --------- ------------- - ----- -- ----- -- ----- -- - ----- --------- - -------------- ------------------------------ -- ------- -- ----- ------ ------------------------------ -- ------- -- ----- ------ ------------------------------ -- ------- -- ----- ------ ------------------------------ -- ------- ---------- ----- ----- --------- -------------------- - --- - - -- --- - - -- ----- ------ - ----- -- --- -- - --- - - --- - - ----- --- - --------------------- ------------------------------ -- - ------------------------------ -- - ------------------------------ -- - ------------------------------ -- - ------------------------------ -- -
本题详细解读
迭代器 (Iterator) 详解
迭代器协议
迭代器协议定义了如何生成一个序列的值。它是一个对象,需要实现一个 next()
方法。这个 next()
方法返回的对象必须包含两个属性:
value
: 迭代的当前值。done
: 一个布尔值,表示迭代是否完成。当为true
时,表明没有更多值可以迭代了。
可迭代对象 (Iterable)
一个对象如果拥有一个名为 [Symbol.iterator]
的方法,并且这个方法返回一个符合迭代器协议的对象,那么它就是一个可迭代对象。JavaScript 中一些内置的数据结构,例如 Array
, Map
, Set
和 String
都是可迭代对象。
const arr = [1, 2, 3]; const iterator = arr[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}
使用场景
for...of
循环:for...of
循环可以直接遍历可迭代对象。- 展开语法 (...): 可以将可迭代对象展开为数组或函数参数。
- 解构赋值: 可以使用解构语法从可迭代对象中提取值。
- 自定义迭代: 当你需要自定义数据结构的遍历方式时,可以实现自定义的迭代器。
生成器 (Generator) 详解
生成器函数
生成器函数使用 function*
语法定义,它并非立即执行,而是返回一个生成器对象。
-- -------------------- ---- ------- --------- ------------- - --------------------- ----- -- ------------------ ---- ----- -- ------------------ ---- ----- -- ------------------- - ----- --- - -------------- ------------------- ------- ----------- -- ----- -- ----- - ----------------- ---- ----------- -- ----- - -- ---- - ----------- -- --- ----------------- ----
yield
关键字
yield
关键字用于暂停生成器函数的执行,并返回一个值。每次调用生成器对象的 next()
方法时,生成器函数会从上次 yield
语句处恢复执行,直到遇到下一个 yield
或者函数结束。
yield*
关键字
yield*
关键字可以委托另一个生成器或可迭代对象。
-- -------------------- ---- ------- --------- ------------------ - ----- ---- ----- ---- - --------- --------------- - ----- -- ------ ------------------- ----- -- - ----- --- - ---------------- ------------------------ -- - ------ -- ----- ----- - ------------------------ -- - ------ ---- ----- ----- - ------------------------ -- - ------ ---- ----- ----- - ------------------------ -- - ------ -- ----- ----- - ------------------------ -- - ------ ---------- ----- ---- -
使用场景
- 生成无限序列: 由于生成器函数可以暂停和恢复执行,因此可以用于生成无限序列的值。
- 处理异步操作: 可以结合
async/await
来处理异步操作,使得异步代码看起来更像是同步代码。 - 状态机: 可以实现状态机,根据不同的状态生成不同的值。
- 惰性求值: 生成器只在需要的时候才计算值,可以节省资源。
生成器与迭代器的关系
生成器函数返回一个迭代器,因此生成器天然就是一个迭代器。 它使用 yield
提供 value
,并且通过内部逻辑控制 done
属性。 生成器让开发者更容易定义迭代行为,无需手动创建迭代器。