要使自定义对象支持for...of,必须实现Symbol.iterator方法并返回符合迭代器协议的对象(含next()方法,返回{value, done});推荐使用生成器函数(function*),因其天然满足协议且自动管理状态。

让自定义对象支持 for...of,核心是实现 Symbol.iterator 方法,并确保它返回一个符合迭代器协议的对象——即带有 next() 方法,且每次调用返回 { value, done } 结构。
必须返回一个真正的迭代器对象
不能只写一个函数或直接返回值,必须返回一个含 next() 的对象。常见错误是:
-
[Symbol.iterator]() { return this; }—— 如果this没有next(),会报错“is not iterable” -
[Symbol.iterator]() { return { value: 1 }; }—— 缺少next(),不满足协议 - 用箭头函数写
next导致this绑定失效,访问不到原对象数据
推荐用生成器函数(最简洁可靠)
生成器函数(function*)天然返回合规迭代器,自动管理状态、暂停恢复和 done 逻辑:
const range = {
from: 1,
to: 3,
*[Symbol.iterator]() {
for (let i = this.from; i <= this.to; i++) {
yield i;
}
}
};
for (const n of range) console.log(n); // 1, 2, 3
它还能直接用于扩展运算符、Array.from 等场景,无需额外适配。
立即学习“Java免费学习笔记(深入)”;
手动实现 next(适合精细控制)
当需要懒加载、分页、副作用处理等逻辑时,可手动构造迭代器对象:
- 在
[Symbol.iterator]内部用闭包保存遍历状态(如let index = 0) - 返回的对象必须有
next()方法,不能是箭头函数(需正确访问闭包变量) - 每次调用
next()都要返回{ value: ..., done: false/true },done: true后仍应返回{ value: undefined, done: true }
例如遍历对象的值:
const obj = { a: 10, b: 20, c: 30 };
obj[Symbol.iterator] = function() {
const values = Object.values(this);
let i = 0;
return {
next() {
if (i < values.length) {
return { value: values[i++], done: false };
}
return { value: undefined, done: true };
}
};
};
注意多次遍历必须返回新迭代器
for...of 每次执行都会调用 [Symbol.iterator]()。如果该方法返回同一个迭代器实例,第二次遍历时会从上次结束位置继续,甚至立即终止:
- ✅ 正确:每次返回全新闭包或新生成器实例
- ❌ 错误:把
let i = 0提到方法外,或复用同一对象
生成器函数默认满足这点;手动实现时,确保状态变量定义在 [Symbol.iterator] 函数内部。


















