要让自定义对象支持 for...of 遍历,需部署 symbol.iterator 方法并返回含 next() 的迭代器对象;原生 object 无此方法故报错,而数组等内置该接口;可手动在对象上定义 [symbol.iterator],返回按需生成 {value, done} 的迭代器。

要让自定义对象支持 for...of 遍历,关键是在对象上部署 Symbol.iterator 方法。这个方法必须返回一个**迭代器对象**,而该迭代器对象需具备 next() 方法,每次调用都返回形如 { value, done } 的对象。
为什么对象默认不能 for...of?
原生对象(Object)的原型链上没有 Symbol.iterator 方法,所以直接 for (let v of obj) 会报错:obj is not iterable。而数组、字符串、Set、Map 等都已内置该接口。
如何给对象添加 Symbol.iterator
只需在对象自身或其原型上定义一个名为 [Symbol.iterator] 的方法,返回一个满足迭代器协议的对象:
- 该方法本身不接收参数,返回值必须是迭代器对象(含
next()函数) -
next()每次调用应返回{ value: 当前值, done: 布尔值 } - 当
done: true时,遍历终止,后续调用仍应返回{ value: undefined, done: true }
示例:让普通对象按属性值遍历
const person = { name: 'Alice', age: 30, city: 'Beijing' };person[Symbol.iterator] = function () {
const values = Object.values(this);
let index = 0;
return {
next() {
if (index
return { value: values[index++], done: false };
} else {
return { value: undefined, done: true };
}
}
};
};
for (const val of person) {
console.log(val); // 'Alice', 30, 'Beijing'
}
更灵活的遍历控制方式
你可以根据需求定制遍历逻辑,比如只遍历自有可枚举属性、按特定顺序、跳过某些值、甚至生成无限序列:
- 用
Object.keys(this)遍历键名,Object.entries(this)遍历键值对 - 结合闭包保存内部状态(如计数器、游标位置)
- 返回的
value可以是任意类型,包括对象、函数或计算结果 - 支持展开运算符:
[...person]会自动调用Symbol.iterator
常见注意事项
确保实现符合规范,避免运行时错误:
-
Symbol.iterator必须用方括号写法:obj[Symbol.iterator] = ...,不能用点号 - 多次调用
[Symbol.iterator]()应返回**新迭代器**(否则多个for...of会互相干扰) -
next()必须是无参函数;传参会被忽略 - 不要在
next()中修改被遍历对象结构,否则行为不可预测











