要让 for...of 遍历自定义对象,需实现 symbol.iterator 方法并返回含 next() 的迭代器对象;next() 必须返回 {value, done} 形式对象,done 为 false 时 value 必须存在。

要让 for...of 循环能遍历自定义对象,关键在于该对象必须提供一个符合迭代协议的方法:即拥有 [Symbol.iterator] 方法,且该方法返回一个**迭代器对象**(具有 next() 方法的对象)。
确保 Symbol.iterator 方法存在并返回合法迭代器
Symbol.iterator 是一个内置 symbol,for...of 会自动调用它来获取迭代器。这个方法不能是普通函数,必须返回一个对象,该对象至少有 next() 方法;next() 每次调用应返回形如 { value: ..., done: true|false } 的对象。
- 如果
next()返回{ done: true },表示遍历结束,value可选(通常忽略) - 如果
done为false,则value必须存在,它就是当前迭代出的值 - 迭代器可以是可多次使用的(如数组),也可以是一次性的(如生成器函数返回的迭代器)
简单示例:手动实现一个计数器迭代器
下面是一个从 0 开始、最多输出 3 个数字的自定义可迭代对象:
const counter = {
[Symbol.iterator]() {
let step = 0;
return {
next() {
if (step for (const num of counter) {
console.log(num); // 输出:0, 1, 2
}
常见错误与注意事项
实际编写时容易踩坑,需特别注意:
-
别忘了方括号语法:
[Symbol.iterator]必须用计算属性名写法,写成Symbol.iterator()或"Symbol.iterator"都无效 -
next() 必须是函数,不能是箭头函数(若需闭包):箭头函数无法正确绑定
this,而迭代器常依赖闭包保存状态(如上面的step) -
不要在每次调用
[Symbol.iterator]时复用同一个迭代器对象:否则多次for...of会互相干扰;应每次返回**新创建的迭代器**(如示例中每次调用都新建一个带独立step的对象) -
value 和 done 字段名大小写敏感:必须是小写的
value和done,写成Value或DONE不会被识别
更实用的例子:遍历对象自身的键值对
JavaScript 对象默认不可被 for...of 遍历,但你可以让它像 Map 一样支持键值对迭代:
const obj = { a: 1, b: 2, c: 3 };
obj[Symbol.iterator] = function* () {
for (const key of Object.keys(this)) {
yield [key, this[key]];
}
};
<p>for (const [key, value] of obj) {
console.log(<code>${key}: ${value}</code>); // a: 1, b: 2, c: 3
}</p>
这里用了生成器函数(function*),它天然返回符合协议的迭代器,写法更简洁、状态管理更安全。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











