可迭代对象需实现Symbol.iterator方法并返回符合迭代器协议的对象。1. 最简实现每次next()返回固定值后done为true;2. 可遍历内部数据如NumberRange类按范围生成数字;3. 生成器函数*iterator()可简化实现,自动满足协议。

在 JavaScript 中,只要给自定义对象添加 Symbol.iterator 方法,并让它返回一个符合迭代器协议的对象(即有 next() 方法、返回 { value, done } 形式的对象),这个对象就能被 for...of、扩展运算符([...obj])、解构、Array.from() 等语法识别为可迭代对象。
1. 实现基础的 Symbol.iterator 方法
最简实现是让对象每次调用 next() 返回一个固定值,然后标记 done: true:
const myObj = {
[Symbol.iterator]() {
let done = false;
return {
next() {
if (!done) {
done = true;
return { value: 'hello', done: false };
}
return { value: undefined, done: true };
}
};
}
};
for (const item of myObj) {
console.log(item); // 输出: 'hello'
}
2. 让对象遍历内部数据(如数组或属性)
常见需求是让对象像数组一样逐个返回自己的数据。例如封装一个只读的数字列表:
class NumberRange {
constructor(start, end) {
this.start = start;
this.end = end;
}
[Symbol.iterator]() {
let current = this.start;
return {
next: () => {
if (current <= this.end) {
return { value: current++, done: false };
}
return { value: undefined, done: true };
}
};
}
}
const range = new NumberRange(1, 3);
console.log([...range]); // [1, 2, 3]
for (const n of range) console.log(n); // 1, 2, 3
3. 支持多次遍历(避免状态污染)
注意:Symbol.iterator 方法必须每次调用都返回**新迭代器**,否则多次 for...of 会互相影响(比如第二次遍历时直接返回 done: true):
立即学习“Java免费学习笔记(深入)”;
在调试 Java 后端 API 故障时使用此技能,尤其适用于以下任务:分析日志、跨 Controller、Service 和 Mapper 层追踪请求、定位异常根因、检查 SQL 执行或参数流转,以及生成简洁的诊断结论与修复方案。
- ✅ 正确:每次调用
[Symbol.iterator]()都新建闭包或重置计数器 - ❌ 错误:把迭代状态(如
index)存在对象实例上,且不重置
反例(错误):
class BadCounter {
constructor() {
this.index = 0;
}
[Symbol.iterator]() {
return {
next: () => {
if (this.index < 3) return { value: this.index++, done: false };
return { value: undefined, done: true };
}
};
}
}
const c = new BadCounter();
console.log([...c]); // [0, 1, 2]
console.log([...c]); // [] ← 第二次为空!因为 index 已到 3
4. 复用已有的可迭代对象(推荐简洁写法)
如果内部已有数组、Set、Map 等原生可迭代结构,可以直接委托它们的迭代器:
class Collection {
constructor(items = []) {
this.items = [...items]; // 存为数组
}
[Symbol.iterator]() {
return this.items[Symbol.iterator](); // 直接返回数组的迭代器
}
}
const coll = new Collection(['a', 'b', 'c']);
console.log(Array.from(coll)); // ['a', 'b', 'c']
甚至可以更简写成:[Symbol.iterator]() { return this.items.values(); }(对数组等有效)。
不复杂但容易忽略:确保 next() 返回的对象结构准确,done 是布尔值,value 在 done: true 时可省略(但建议显式返回 undefined 更清晰)。

















