javascript中通过实现symbol.iterator方法或使用function*生成器函数,可使对象支持for...of等遍历语法;生成器自动满足迭代器协议,支持懒加载、异步及资源清理。

JavaScript 中通过实现 Symbol.iterator 方法,让对象具备可迭代能力,从而支持 for...of、扩展运算符、解构等原生遍历语法。关键不是“写个循环”,而是“告诉 JavaScript 你希望怎么一步步产出值”。
让任意对象变成可迭代对象
只要对象的 [Symbol.iterator] 方法返回一个符合迭代器协议的对象(即有 next() 方法,返回 { value, done } 形式的对象),它就能被遍历。
例如,实现一个倒序遍历数组的自定义迭代器:
const reverseArray = arr => {
return {
[Symbol.iterator]() {
let index = arr.length - 1;
return {
next() {
if (index >= 0) {
return { value: arr[index--], done: false };
} else {
return { value: undefined, done: true };
}
}
};
}
};
};
<p>const nums = [1, 2, 3];
for (const n of reverseArray(nums)) {
console.log(n); // 3 → 2 → 1
}</p>用生成器函数简化迭代器编写
手写 next() 容易出错,而 function* 生成器函数会自动返回合规迭代器,语义更清晰、状态更安全。
- 函数内用
yield暂停并产出一个值;每次调用next()就恢复执行到下一个yield - 函数结束时自动返回
{ done: true },无需手动判断边界 - 支持异步:用
async function*可产出 Promise,配合for await...of
改写上面的例子:
function* reverseIterator(arr) {
for (let i = arr.length - 1; i >= 0; i--) {
yield arr[i];
}
}
<p>const iter = reverseIterator([10, 20, 30]);
console.log(iter.next()); // { value: 30, done: false }
console.log(iter.next()); // { value: 20, done: false }
console.log([...reverseIterator([10, 20, 30])]); // [30, 20, 10]</p>控制遍历节奏与提前终止
迭代器协议本身不强制遍历全部元素——消费者(如 for...of)决定何时调用 next(),甚至可中途跳出。你还可以在迭代器中响应 return() 或 throw()(需生成器或手动实现)来清理资源。
- 若迭代器对象有
return()方法,break或return语句会触发它(仅限生成器或手动添加) - 生成器中使用
try...finally可确保清理逻辑执行,哪怕提前退出 - 避免在
next()中做重操作(如网络请求),除非明确需要懒加载
示例:带清理的计数器迭代器
function* countdown(max) {
try {
while (max > 0) {
yield max--;
}
} finally {
console.log("计数结束,释放资源");
}
}
<p>const count = countdown(3);
console.log(count.next()); // { value: 3, done: false }
console.log(count.return?.()); // { value: undefined, done: true } + 打印日志</p>实际场景建议
- 需要惰性计算(比如处理大文件行、无限序列、搜索结果流)→ 优先用
function* - 封装已有数据结构(如树、图)的特定遍历顺序(中序、层序、DFS 路径)→ 实现
[Symbol.iterator] - 想让类实例支持展开或解构 → 在类原型上定义
[Symbol.iterator]或用生成器方法 - 注意不要在迭代器中修改被遍历的原始数据,否则可能引发不可预期行为
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











