要让自定义对象支持for-of,需实现Symbol.iterator方法并返回符合迭代器协议的对象:该方法必须返回含next()的对象,next()每次调用须返回{value: ..., done: true|false}。

让自定义对象支持 for-of,核心就一条:在对象上实现 Symbol.iterator 方法,且该方法返回一个符合迭代器协议的对象。
必须满足的两个条件
JS 引擎执行 for-of 时,会按顺序检查:
- 对象是否有
[Symbol.iterator]属性(可迭代协议) - 调用这个属性后,返回的对象是否拥有
next()方法(迭代器协议) -
next()每次调用必须返回形如{ value: ..., done: true|false }的对象
最简可行实现示例
比如一个普通用户对象:
添加迭代器,让它遍历所有属性值:
user[Symbol.iterator] = function() {const keys = Object.keys(this);
let index = 0;
return {
next() {
if (index return { value: this[keys[index++]], done: false };
} else {
return { value: undefined, done: true };
}
}
};
};
之后就能直接用:
for (const val of user) {console.log(val); // '李四', 'admin', 'active'
}
常见变体与实用技巧
- 想遍历键名?把
this[keys[index]]改成keys[index] - 想遍历
[key, value]对?返回{ value: [keys[index], this[keys[index]]], done: false } - 需要复用逻辑?把迭代器封装成独立函数,多个对象共用同一套实现
- 避免闭包陷阱:确保
this在next中指向正确——建议用箭头函数或显式绑定
注意边界情况
迭代器一旦返回 { done: true },后续调用 next() 也应保持一致,返回 { value: undefined, done: true }。否则可能引发不可预期行为,比如某些库内部多次调用 next() 做探测。


















