要让自定义对象支持for...of等原生迭代语法,需部署Symbol.iterator方法并返回符合迭代器协议的对象;该方法必须返回带next()且每次调用返回{value,done}的对象,且每次调用应创建全新迭代器实例以保证遍历独立。
![如何利用 [symbol.iterator] 为自定义对象部署迭代行为](https://img.php.cn/upload/article/001/242/473/178030204421364.png)
要让自定义对象支持 for...of、扩展运算符([...obj])、解构赋值等原生迭代语法,关键是在对象上部署 [Symbol.iterator] 方法,并确保它返回一个符合迭代器协议的对象。
理解 Symbol.iterator 的作用
Symbol.iterator 是一个内置 symbol,它本身不是迭代器,而是一个“入口键”:当语言检测到需要遍历某个对象时(比如执行 for (const x of obj)),会自动查找并调用该对象的 [Symbol.iterator]() 方法。这个方法必须返回一个迭代器对象——即带有 next() 方法的对象,且每次调用 next() 都应返回形如 { value, done } 的对象。
手动实现迭代器对象(适合学习原理)
适用于需精细控制状态或兼容性要求高的场景。注意以下要点:
- 不能用箭头函数定义
[Symbol.iterator],否则this会丢失 - 每次调用该方法都应返回**全新迭代器实例**,避免多个循环共享同一状态导致互相干扰
- 内部状态(如索引
index)需在闭包中初始化,保证每次遍历独立
示例:让类数组对象可迭代
const obj = {data: ['x', 'y', 'z'],
[Symbol.iterator]() {
let i = 0;
return {
next: () => {
if (i return { value: this.data[i++], done: false };
} else {
return { done: true };
}
}
}
}
};
for (const item of obj) console.log(item); // x, y, z
用生成器函数简化实现(推荐方式)
生成器函数(function*)天然满足迭代器协议:调用后返回一个具备 next() 方法的对象,yield 自动封装 {value, done} 返回逻辑,无需手动维护索引或判断边界。
- 写法简洁,不易出错
- 自动暂停/恢复执行,适合异步或复杂遍历逻辑
- 支持
yield*委托其他可迭代对象
示例:实现数字范围迭代
const range = {from: 10,
to: 12,
*[Symbol.iterator]() {
for (let i = this.from; i yield i;
}
}
};
console.log([...range]); // [10, 11, 12]
验证与使用场景
部署完成后,对象即可用于所有原生迭代上下文:
for (const v of obj) { ... }-
const arr = [...obj];或Array.from(obj) -
const [a, b] = obj;(解构赋值) -
new Set(obj)、new Map(iterable)等构造函数
注意:若对象已有 [Symbol.iterator],但返回值不符合协议(如没 next 方法,或 next() 不返回 {value, done}),则迭代会失败或行为异常。

















