JavaScript可用闭包封装迭代状态,返回每次调用返回下一个值的函数;核心是将索引等状态私有化在闭包内,如createIterator(arr)中let index=0,返回函数内通过闭包访问并更新index。

JavaScript 中可以用闭包封装迭代状态,返回一个每次调用都返回下一个值的函数,从而模拟迭代器行为。核心是把索引或当前状态私有化在闭包内,避免外部直接修改。
基础闭包迭代器:遍历数组
最常见的是为数组创建一个“懒执行”的迭代器函数:
function createIterator(arr) {
let index = 0;
return function() {
if (index < arr.length) {
return { value: arr[index++], done: false };
} else {
return { value: undefined, done: true };
}
};
}
const next = createIterator(['a', 'b', 'c']);
console.log(next()); // { value: 'a', done: false }
console.log(next()); // { value: 'b', done: false }
console.log(next()); // { value: 'c', done: false }
console.log(next()); // { value: undefined, done: true }
这里 index 被闭包捕获,每次调用 next() 都操作同一个私有变量,实现状态保持。
兼容 ES6 迭代协议(Symbol.iterator)
若想让对象能被 for...of、... 扩展运算符等原生语法消费,需返回带 [Symbol.iterator]() 方法的对象,并在其中返回符合迭代器协议的闭包函数:
立即学习“Java免费学习笔记(深入)”;
function createIterable(arr) {
return {
[Symbol.iterator]() {
let index = 0;
return {
next() {
if (index < arr.length) {
return { value: arr[index++], done: false };
}
return { value: undefined, done: true };
}
};
}
};
}
const iterable = createIterable([10, 20, 30]);
for (const x of iterable) {
console.log(x); // 10, 20, 30
}
注意:闭包嵌套两层——外层闭包保存 arr,内层闭包保存 index,确保每次调用 iterable[Symbol.iterator]() 都获得独立状态。
支持重置与多实例的进阶写法
如果需要多次遍历或多个独立迭代器,不应共享状态。可把闭包逻辑封装成工厂函数,每次调用都生成新状态:
- 用函数返回迭代器对象(非单例),保证每个 iterator 互不干扰
- 可额外暴露 reset() 方法(需把状态变量改为对象属性并暴露接口)
- 例如:const it1 = createIterator([1,2]); const it2 = createIterator([1,2]); —— 两者独立计数
适用场景与注意事项
- 适合轻量级、一次性、状态简单的迭代逻辑(如配置列表、枚举序列)
- 不适合替代 Generator 函数(后者原生支持 yield、异步暂停、错误传播等)
- 闭包会保留对外部变量的引用,注意避免意外的内存驻留(比如大数组长期被闭包持有)
- 返回的迭代器不符合 IteratorResult 类型时,某些工具(如 Array.from)可能无法识别,建议严格返回 {value, done} 结构


















