JavaScript迭代协议是一套原生识别的接口约定,使对象能声明“可被遍历”(通过[Symbol.iterator]返回新迭代器)并定义遍历步骤(Iterator的next()返回{value, done}),生成器函数是最简洁可靠的实现方式。

JavaScript 迭代协议不是语法糖,而是一套可被语言原生识别的接口约定。它让对象“告诉”引擎“我该怎么被遍历”,从而统一支持 for...of、展开运算符(...)、解构赋值、Array.from() 等多种语法。
Iterable 协议:对象如何声明“我能被遍历”
一个对象只要在自身或原型链上定义了 [Symbol.iterator] 方法,且该方法是无参函数、每次调用都返回一个符合 Iterator 协议的对象,它就是可迭代的。
- 原生可迭代类型包括:
Array、String、Map、Set、TypedArray、NodeList、arguments等 -
[Symbol.iterator]必须返回**新创建的迭代器实例**,否则多次遍历会共享状态(比如同一个数组的values()多次调用互不干扰,但手动实现时若复用内部计数器就可能出错) - 推荐用生成器函数实现该方法,天然满足“每次返回全新迭代器”和“自动管理
done/value”的要求
Iterator 协议:遍历动作如何一步步执行
迭代器是一个拥有 next() 方法的对象,每次调用返回形如 { value, done } 的结果:
-
done: true表示遍历结束;此后再调用next()应始终返回{ value: undefined, done: true } -
value可为任意值,包括undefined(注意:不能仅靠value === undefined判断是否结束,必须看done) - 迭代器本身也可以是可迭代的——只需在迭代器对象上也实现
[Symbol.iterator]() { return this; }
生成器:最简洁可靠的迭代器工厂
用 function* 声明的函数,调用后自动返回符合 Iterator 协议的对象。它把状态暂停、恢复、done 控制等细节全部封装好,避免手动维护逻辑出错。
-
yield是next()的触发点:每次调用next(),函数从上次暂停处继续,执行到下一个yield或函数结束 - 函数自然返回时,
done自动设为true;也可显式用return value提前终止并设置最终value - 适合实现惰性序列(如无限列表、分页流、树的深度优先遍历)
典型应用场景与实用技巧
迭代协议不只是理论机制,它已深度融入语言生态:
-
for...of循环底层就是反复调用[Symbol.iterator]().next(),直到done: true - 扩展运算符(
[...iterable])和解构([a, b] = iterable)都依赖该协议提取值 -
Promise.all(iterable)、Map(iterable)、Array.from(iterable)等 API 都接受任何可迭代对象 - 自定义数据结构(如链表、范围、文件行读取器)只需实现
[Symbol.iterator],就能无缝接入现有工具链
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











