要使自定义对象支持for...of遍历,必须实现可迭代协议:在对象上定义[symbol.iterator]方法,且该方法返回一个具有next()方法的迭代器对象,next()每次调用须返回{value: ..., done: true|false}格式的对象。

让自定义对象支持 for...of 遍历,核心是实现可迭代协议:在对象上部署 [Symbol.iterator] 方法,且该方法必须返回一个符合迭代器协议的对象。
必须满足的两个基本条件
缺一不可:
-
方法名必须是
[Symbol.iterator](注意方括号语法,不能写成点号或字符串) -
该方法必须返回一个迭代器对象:即拥有
next()方法,且每次调用next()都返回形如{ value: ..., done: true|false }的对象
手写一个基础迭代器(适合简单容器)
适用于内部有数组、列表等线性数据的自定义对象。关键在于闭包保存状态(如索引),避免外部干扰:
用于 inference.sh 的 JavaScript/TypeScript SDK,可运行 AI 应用、构建代理、集成 150+ 模型。包名:@inferencesh/sdk(npm install),完整 TypeScript 支持。
const myContainer = {
data: ['a', 'b', 'c'],
[Symbol.iterator]() {
let index = 0;
const self = this;
return {
next() {
if (index
<h3>复用已有迭代器(推荐用于封装数组/Map/Set)</h3>
<p>如果内部数据本身已是可迭代的(比如 <code>this.items</code> 是数组),直接委托更简洁、安全、且天然支持多次遍历:</p>
- 不用手动管理索引和边界
- 自动继承原生迭代器的所有能力(如解构、展开运算符)
- 每次调用
[Symbol.iterator]()都返回新实例,不会互相影响
class List {
constructor(items = []) {
this.items = items;
}
[Symbol.iterator]() {
return this.items[Symbol.iterator](); // 直接返回数组的迭代器
}
}
const list = new List([10, 20, 30]);
console.log([...list]); // [10, 20, 30]
for (const x of list) console.log(x); // 10 20 30
常见错误与避坑提醒
这些写法会导致 for...of 报错 “is not iterable”:
- 只加了
[Symbol.iterator]() { return this; },但this没有next()方法 - 返回的是普通对象(如
{ value: 1, done: false }),而不是带next()的迭代器对象 - 把
[Symbol.iterator]写成字符串属性:"Symbol.iterator"或Symbol.iterator.toString() - 多次
for...of同一个对象却只返回同一个迭代器实例(状态被共享),应确保每次调用都新建迭代器










