迭代器和生成器是ES6引入的用于自定义和控制迭代流程的强大工具。它们构成了JavaScript中for...of循环和异步编程的基础,让你能够按需、懒加载地处理数据序列。
![图片[1]-什么是迭代器和生成器?-速码派](http://www.sumapai.com/wp-content/uploads/2026/01/7e9d2887a2e448ee96835e3d2a57e9bctplv-tb4s082cfz-aigc_resize_1080_1080-2-1024x683.webp)
迭代器协议
迭代器是一个带有特定接口的对象。它必须有一个next()方法,该方法返回一个包含value和done两个属性的对象。value是当前迭代的值,done是一个布尔值,表示迭代是否已完成。
function createCounterIterator(max) {
let count = 1;
return {
next() {
if (count <= max) {
return { value: count++, done: false };
}
return { value: undefined, done: true };
}
};
}
const iterator = createCounterIterator(3);
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
任何实现了这种next()方法的对象都被称为迭代器。你可以手动调用next()来逐个获取值,直到done为true。
可迭代协议
一个对象要成为可迭代的(即可被for...of循环),它必须实现@@iterator方法,即拥有一个键为Symbol.iterator的属性。该方法返回一个迭代器对象。
const myIterable = {
[Symbol.iterator]() {
return createCounterIterator(3);
}
};
for (let value of myIterable) {
console.log(value); // 依次输出 1, 2, 3
}
数组、字符串、Map、Set等内置类型之所以可以被for...of遍历,正是因为它们内建了Symbol.iterator方法。
生成器函数
手动实现迭代器协议略显繁琐。生成器函数则提供了一种更简洁的语法来创建迭代器。在function关键字后加一个星号*就定义了一个生成器函数。
function* counterGenerator(max) {
for (let i = 1; i <= max; i++) {
yield i;
}
}
const gen = counterGenerator(3);
console.log(gen.next()); // { value: 1, done: false }
for (let num of counterGenerator(3)) {
console.log(num); // 依次输出 1, 2, 3
}
生成器函数在调用时不会立即执行,而是返回一个生成器对象(它同时遵守迭代器协议)。当调用其next()方法时,函数会执行到下一个yield表达式,并将yield后面的值作为value返回,然后函数暂停。下次调用next()时,再从暂停处继续执行。
生成器的强大之处
生成器不仅简化了迭代器的创建,还支持双向通信。你可以通过next()方法向生成器内部传递值,这个值会成为上次yield表达式的返回值。
function* twoWayGenerator() {
const received = yield 'Hello';
yield `You said: ${received}`;
}
const tw = twoWayGenerator();
console.log(tw.next()); // { value: 'Hello', done: false }
console.log(tw.next('World')); // { value: 'You said: World', done: false }
此外,生成器与yield*表达式结合,可以轻松地委托给另一个可迭代对象或生成器,实现递归或组合迭代。
迭代器和生成器是处理无限序列(如斐波那契数列)、懒加载数据、状态机以及实现自定义数据结构的理想选择。它们也是现代异步编程模式async/await的底层基础,其中async函数本质上就是一种特殊的生成器。




















暂无评论内容