JavaScript自定义对象实现迭代器接口需添加[Symbol.iterator]方法,返回含next()的对象;next()每次返回{value,done},支持for...of、扩展运算符等;可手写或用生成器函数实现。

JavaScript 中自定义对象要实现迭代器接口,核心是给该对象添加一个 [Symbol.iterator] 方法,且这个方法必须返回一个符合迭代器协议的对象(即具有 next() 方法,每次调用返回 { value, done } 形式的对象)。
让对象支持 for...of 和扩展运算符
只要实现了 [Symbol.iterator],对象就能被 for...of 遍历、用在 [...obj] 扩展运算中,或传给 Array.from() 等接受可迭代对象的 API。
例如:
const obj = { a: 1, b: 2, c: 3 };obj[Symbol.iterator] = function* () {
for (let key of Object.keys(this)) {
yield this[key];
}
};
for (const val of obj) console.log(val); // 1, 2, 3
手动实现 next() 迭代器(非生成器写法)
如果不想用生成器函数(function*),也可以手写一个返回迭代器对象的 [Symbol.iterator] 方法:
立即学习“Java免费学习笔记(深入)”;
- 该方法内部维护一个索引或状态(如当前遍历到第几个属性)
- 每次调用
next()返回{ value: ..., done: true/false } - 当
done为true后,后续调用仍应返回{ value: undefined, done: true }
list[Symbol.iterator] = function () {
let i = 0;
return {
next: () => {
if (i
return { value: this.items[i++], done: false };
} else {
return { value: undefined, done: true };
}
}
};
注意迭代器的“惰性”和“单次性”
迭代器是惰性求值的:不调用 next() 就不执行逻辑;也是单次性的:同一个迭代器对象只能遍历一次。多次 for...of 同一个对象,每次都会重新调用 [Symbol.iterator] 创建新迭代器。
所以不要把迭代器状态存在对象自身上(除非有意共享),而应封装在每次返回的迭代器闭包内。
常见用途与建议
- 遍历自定义集合类(如 Stack、Queue、Tree)时,优先实现
[Symbol.iterator]提升可用性 - 想同时支持键、值、键值对遍历时,可提供
keys()、values()、entries()方法,并让它们也返回可迭代对象 - 生成器函数是最简洁的实现方式,推荐在逻辑不复杂时直接使用
function*


















