Iterable 和 Iterator 是 JavaScript 中实现遍历的协议,Iterable 是拥有返回 Iterator 的 [Symbol.iterator] 方法的对象,Iterator 是具有 next() 方法并返回 {value, done} 对象的对象;for...of 等语法依赖该协议调用链。

JavaScript 中的 Iterable 和 Iterator 是实现数据遍历能力的底层协议,不是具体类型,而是一套约定接口。理解它们的关键在于:Iterable 是“可被遍历的对象”,Iterator 是“执行遍历的动作对象”。二者通过 [Symbol.iterator] 方法连接。
Iterable 协议:谁可以被 for...of 遍历?
一个对象只要拥有无参、返回 Iterator 对象的 [Symbol.iterator] 方法,就是 Iterable。原生支持该协议的有 Array、String、Map、Set、TypedArray、arguments、NodeList 等。
手动实现一个 Iterable 很简单:
const myIterable = {
[Symbol.iterator]() {
let step = 0;
return {
next() {
step++;
if (step for (const item of myIterable) {
console.log(item); // item1 → item2 → item3
}
注意:[Symbol.iterator] 必须是函数,每次调用都应返回**全新**的 Iterator,否则多次遍历会互相干扰(比如数组的 values() 方法就满足这点)。
Iterator 协议:遍历如何一步步进行?
Iterator 是一个具有 next() 方法的对象,该方法返回形如 { value: any, done: boolean } 的结果对象:
-
value:当前步产出的值(可以是
undefined,即使done: false) -
done:布尔值,
true表示遍历结束;一旦为true,后续调用next()应始终返回{ value: undefined, done: true }
Iterator 可以是“惰性”的(如生成器函数返回的 Iterator),也可以是“预计算”的(如数组 entries() 返回的)。关键不在于怎么算,而在于是否符合 next() 的契约。
生成器函数:最自然的 Iterator 工厂
function* 声明的生成器函数,调用后自动返回符合 Iterator 协议的对象。它把状态暂停/恢复的逻辑封装好了,避免手动维护 done 和 value 的繁琐。
function* countdown(n) {
while (n > 0) {
yield n; // 暂停并产出 n
n--;
}
}
<p>const iter = countdown(3);
console.log(iter.next()); // { value: 3, done: false }
console.log(iter.next()); // { value: 2, done: false }
console.log(iter.next()); // { value: 1, done: false }
console.log(iter.next()); // { value: undefined, done: true }</p>
生成器内部的 yield 就是 next() 的触发点;函数返回(或执行完)时,自动设 done: true。这是语言层面对 Iterator 协议最优雅的支持。
for...of 与展开语法背后的调用链
所有使用 for...of、[...iterable]、Array.from(iterable)、yield* 的地方,引擎都会:
- 检查目标是否有
[Symbol.iterator]方法 - 调用它获取 Iterator 对象
- 循环调用该 Iterator 的
next(),直到done === true
如果目标没有实现 Iterable 协议,就会报错 TypeError: X is not iterable。这也是为什么普通对象默认不可 for...of —— 它没定义 [Symbol.iterator](除非你手动加)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











