JavaScript中的迭代器和生成器是ES6引入的重要特性,主要用于规范集合遍历逻辑、简化异步流程控制场景下的代码编写。迭代器提供了统一的元素访问方式,生成器则是迭代器实现的一种更便捷的语法糖,二者配合可以让自定义数据结构支持标准的遍历操作。

什么是迭代器
迭代器是一个具有next方法的对象,每次调用next方法会返回一个包含value和done两个属性的结果对象。value表示当前遍历到的元素值,done是布尔值,为true时表示遍历已经结束。
一个标准的迭代器实现示例如下:
// 自定义一个简单的迭代器,遍历1到3的数字
function createIterator() {
let current = 1;
const max = 3;
return {
next: function() {
if (current <= max) {
return { value: current++, done: false };
} else {
return { value: undefined, done: true };
}
}
};
}
const iterator = createIterator();
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 }
什么是生成器
生成器是一种特殊的函数,函数在执行过程中可以暂停,并且后续可以恢复执行。生成器函数通过function*语法定义,函数体内使用yield关键字来暂停执行并返回中间结果,调用生成器函数不会立即执行函数体,而是返回一个生成器对象,该对象本身就是一个迭代器。
生成器的使用示例:
// 生成器函数,生成1到3的数字
function* numberGenerator() {
yield 1;
yield 2;
yield 3;
}
const gen = numberGenerator();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: false }
console.log(gen.next()); // { value: undefined, done: true }
生成器对象除了支持next方法外,还支持return方法提前终止遍历,以及throw方法向生成器内部抛出错误,这些特性让生成器在异步流程控制场景中也有广泛应用。
可迭代对象的定义
可迭代对象是部署了Symbol.iterator方法的对象,该方法调用后会返回一个迭代器对象。只要一个对象具备这个属性,就可以使用for...of循环、扩展运算符...、解构赋值等语法来遍历其内容。
JavaScript内置的数组、字符串、Map、Set都是可迭代对象,我们可以通过以下代码验证:
const arr = [1, 2, 3];
// 数组具有Symbol.iterator方法
console.log(typeof arr[Symbol.iterator]); // function
// 可以使用for...of遍历
for (const item of arr) {
console.log(item); // 依次输出1、2、3
}
如何自定义可迭代对象
自定义可迭代对象只需要给对象添加Symbol.iterator方法,并且该方法返回一个符合迭代器规范的迭代器即可。我们可以使用普通函数实现迭代器,也可以直接使用生成器函数来简化实现。
方式一:普通函数实现迭代器
以下是一个自定义可迭代对象的示例,该对象表示一个范围数字集合,支持遍历指定区间的所有整数:
// 自定义范围对象,包含从start到end的所有整数
class NumberRange {
constructor(start, end) {
this.start = start;
this.end = end;
}
// 实现Symbol.iterator方法
[Symbol.iterator]() {
let current = this.start;
const max = this.end;
return {
next: () => {
if (current <= max) {
return { value: current++, done: false };
} else {
return { value: undefined, done: true };
}
}
};
}
}
const range = new NumberRange(1, 3);
// 可以使用for...of遍历
for (const num of range) {
console.log(num); // 依次输出1、2、3
}
// 也可以使用扩展运算符
console.log([...range]); // [1, 2, 3]
方式二:生成器函数实现迭代器
使用生成器函数实现Symbol.iterator可以更简洁,不需要手动维护迭代器对象的next方法和状态:
class NumberRange {
constructor(start, end) {
this.start = start;
this.end = end;
}
// 使用生成器函数实现Symbol.iterator
*[Symbol.iterator]() {
let current = this.start;
while (current <= this.end) {
yield current;
current++;
}
}
}
const range = new NumberRange(2, 4);
for (const num of range) {
console.log(num); // 依次输出2、3、4
}
注意事项
Symbol.iterator是固定的属性名,不能拼写错误,否则对象不会被识别为可迭代对象。- 迭代器的
next方法必须是无参数或者只接收特定控制参数的,不能依赖外部传入遍历状态。 - 生成器函数内部的
yield只能在生成器函数内部使用,不能在嵌套的普通函数中使用。 - 可迭代对象的遍历是一次性的,遍历结束后如果需要再次遍历,需要重新获取迭代器对象。
掌握迭代器、生成器和可迭代对象的用法,可以让你在处理自定义数据结构遍历、实现异步流程控制时更加得心应手,写出更符合规范、更易维护的JavaScript代码。
JavaScriptiteratorgenerator可迭代对象自定义迭代修改时间:2026-06-21 13:30:37