实现一个迭代器生成函数
手写实现一个可以生成迭代器的函数,支持自定义迭代逻辑,理解 JavaScript 迭代器协议
问题
在 JavaScript 中,迭代器(Iterator)是一种设计模式,它提供了一种统一的方式来遍历各种数据结构。本题要求实现一个迭代器生成函数,使得对象可以被 for...of 循环遍历,并理解迭代器协议的原理。
解答
/**
* 创建一个范围迭代器
* @param {number} start - 起始值
* @param {number} end - 结束值
* @param {number} step - 步长,默认为1
* @returns {Object} 迭代器对象
*/
function createRangeIterator(start, end, step = 1) {
let current = start;
return {
// 实现迭代器协议:必须有 next 方法
next() {
if (current < end) {
const value = current;
current += step;
return { value, done: false };
}
return { value: undefined, done: true };
},
// 实现可迭代协议:返回迭代器自身
[Symbol.iterator]() {
return this;
}
};
}
/**
* 创建一个可迭代对象
* @param {Array} data - 数据数组
* @returns {Object} 可迭代对象
*/
function createIterableObject(data) {
return {
[Symbol.iterator]() {
let index = 0;
return {
next() {
if (index < data.length) {
return { value: data[index++], done: false };
}
return { value: undefined, done: true };
}
};
}
};
}
/**
* 使用生成器函数实现迭代器(推荐方式)
* @param {number} start - 起始值
* @param {number} end - 结束值
* @param {number} step - 步长
*/
function* rangeGenerator(start, end, step = 1) {
for (let i = start; i < end; i += step) {
yield i;
}
}
/**
* 创建一个无限迭代器
*/
function createInfiniteIterator() {
let count = 0;
return {
next() {
return { value: count++, done: false };
},
[Symbol.iterator]() {
return this;
}
};
}
使用示例
// 示例1:使用范围迭代器
const rangeIter = createRangeIterator(0, 5);
for (const num of rangeIter) {
console.log(num); // 输出: 0, 1, 2, 3, 4
}
// 示例2:手动调用 next 方法
const iter = createRangeIterator(10, 13);
console.log(iter.next()); // { value: 10, done: false }
console.log(iter.next()); // { value: 11, done: false }
console.log(iter.next()); // { value: 12, done: false }
console.log(iter.next()); // { value: undefined, done: true }
// 示例3:使用可迭代对象
const iterableObj = createIterableObject(['a', 'b', 'c']);
for (const item of iterableObj) {
console.log(item); // 输出: a, b, c
}
// 示例4:使用生成器函数
const generator = rangeGenerator(0, 5, 2);
console.log([...generator]); // [0, 2, 4]
// 示例5:解构赋值
const [first, second, ...rest] = createRangeIterator(1, 6);
console.log(first, second, rest); // 1 2 [3, 4, 5]
// 示例6:无限迭代器(需要手动控制)
const infiniteIter = createInfiniteIterator();
console.log(infiniteIter.next().value); // 0
console.log(infiniteIter.next().value); // 1
console.log(infiniteIter.next().value); // 2
// 示例7:结合数组方法
const rangeArray = Array.from(createRangeIterator(1, 6));
console.log(rangeArray); // [1, 2, 3, 4, 5]
关键点
-
迭代器协议:对象必须实现
next()方法,返回包含value和done属性的对象value:当前迭代的值done:布尔值,表示迭代是否完成
-
可迭代协议:对象必须实现
[Symbol.iterator]方法,返回一个迭代器对象 -
生成器函数:使用
function*和yield关键字是创建迭代器的最简洁方式,自动实现迭代器协议 -
状态管理:迭代器需要维护内部状态(如当前索引、计数器等),每次调用
next()时更新状态 -
惰性求值:迭代器按需生成值,不会一次性计算所有结果,适合处理大数据集或无限序列
-
一次性消费:大多数迭代器只能遍历一次,再次遍历需要重新创建(除非实现了可重置逻辑)
-
应用场景:自定义数据结构遍历、分页数据加载、流式数据处理、惰性计算等
目录