es6迭代器与for...of是天然搭档:前者提供统一遍历接口,后者专用于消费该接口;只要对象实现[symbol.iterator]方法并返回符合协议的迭代器(含next(),返回{value,done}),即可被for...of遍历。

ES6 迭代器(Iterator)和 for...of 是一对天然搭档:迭代器提供统一的遍历接口,for...of 则是专门消费这个接口的语法糖。只要一个对象实现了 [Symbol.iterator] 方法并返回符合迭代器协议的对象(即有 next() 方法,返回 { value, done } 形式的对象),它就能被 for...of 遍历。
哪些对象原生支持 for...of?
多数内置可遍历数据结构默认实现了迭代器协议:
- Array:按索引顺序遍历元素
- String:按 Unicode 字符(非字节)遍历
-
Map:遍历
[key, value]数组 - Set:遍历唯一值
-
TypedArray(如
Uint8Array) - arguments 对象和 NodeList(DOM 查询结果)
手动实现一个迭代器配合 for...of
你可以为任意对象添加 [Symbol.iterator] 方法,让它支持 for...of:
const range = {
from: 1,
to: 3,
[Symbol.iterator]() {
let current = this.from;
return {
next() {
if (current for (const num of range) {
console.log(num); // 输出 1, 2, 3
}
注意:next() 中的 this 指向的是外层迭代器对象(不是 range),所以通常用闭包或箭头函数保存上下文;上面例子中用了普通函数,需确保调用时 this 正确 —— 更稳妥写法是把 current 提前定义在闭包里,或用箭头函数绑定作用域。
生成器函数:最简洁的迭代器写法
ES6 引入 function* 生成器函数,自动返回迭代器对象,大幅简化手动实现:
function* rangeGenerator(from, to) {
for (let i = from; i const iter = rangeGenerator(1, 3);
for (const num of iter) {
console.log(num); // 1, 2, 3
}
生成器函数内部用 yield 暂停执行并产出值,每次 next() 调用恢复执行直到下一个 yield 或函数结束。它天然符合迭代器协议,无需手写 next 和状态管理。
常见误区与注意事项
for...of 只认迭代器协议,不关心对象类型:
-
普通对象(Object)默认不可遍历:没有实现
[Symbol.iterator],直接for...of会报错TypeError: is not iterable - for...in 遍历的是对象的可枚举属性名(字符串),而 for...of 遍历的是可迭代对象的值,二者目的完全不同
-
解构赋值、扩展运算符(...)也依赖迭代器协议,例如
[...range]或const [a, b] = range同样要求range可迭代 -
迭代器只能使用一次:一旦
done: true,后续next()总返回{ value: undefined, done: true };重新遍历需获取新迭代器(如再次调用[Symbol.iterator]()或重执行生成器函数)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











