在不支持 Generator 的环境中,可用闭包模拟迭代器:返回含 next() 方法的对象,闭包保存索引与数据实现状态隔离,next() 返回 {value, done},符合迭代器协议,支持多实例与重置。
在不支持 generator(如早期 javascript 环境或严格限制 `function*` 的沙箱)时,可以用闭包封装状态,手动模拟迭代器行为:返回一个带 next() 方法的对象,每次调用返回 { value, done }。
核心思路:用闭包保存索引和数据引用
闭包能持久化当前遍历位置(如 index)和源数据(如数组),避免暴露内部状态,同时保证多次调用 next() 时状态连续。
- 闭包外层接收原始数据(如数组、类数组或键值对)
- 内层函数返回的迭代器对象,其
next()方法读取并递增私有index - 返回值结构严格符合迭代器协议:
{ value: 当前项, done: 是否结束 }
基础数组迭代器实现
适用于纯数值/任意类型数组,只遍历元素值:
function createArrayIterator(arr) {
let index = 0;
return {
next() {
if (index < arr.length) {
return { value: arr[index++], done: false };
} else {
return { value: undefined, done: true };
}
}
};
}
// 使用示例
const it = createArrayIterator(['x', 'y', 'z']);
console.log(it.next()); // { value: 'x', done: false }
console.log(it.next()); // { value: 'y', done: false }
console.log(it.next()); // { value: 'z', done: false }
console.log(it.next()); // { value: undefined, done: true }
支持键值对的对象迭代器
让普通对象可被 for...of 遍历,返回 [key, value] 形式:
function createObjectEntriesIterator(obj) {
const keys = Object.keys(obj);
let index = 0;
return {
next() {
if (index < keys.length) {
const key = keys[index++];
return { value: [key, obj[key]], done: false };
} else {
return { value: undefined, done: true };
}
}
};
}
const data = { a: 1, b: 2, c: 3 };
const it = createObjectEntriesIterator(data);
for (let [k, v] of { [Symbol.iterator]: () => it }) {
console.log(k, v); // a 1, b 2, c 3
}
注意:要配合 Symbol.iterator 使用,需临时包装成可迭代对象(如上例),否则无法直接用于 for...of。
可重置与多实例控制
闭包实现天然支持“多迭代器互不干扰”,也便于手动重置:
- 每次调用
createArrayIterator(arr)都生成全新闭包,彼此状态隔离 - 如需重置,只需再次调用工厂函数获取新迭代器,无需修改原逻辑
- 不依赖
this或原型链,兼容严格模式和无class环境

















