在 TypeScript(以及 JavaScript)中,迭代器和生成器是用于处理集合数据
(如数组、对象等)的强大工具。它们允许你按顺序访问集合中的元素,并提供了一种控制数据访问的方式。
迭代器(Iterator) 迭代器是一个对象,它定义了一个序列,并且提供了一种方法来访问这个序列的元素。迭代器对象实现了 Iterator 接口,该接口要求它有一个 next() 方法。
Iterable 接口 一个对象如果实现了Iterable接口,那么它就是可迭代的。这个接口要求对象必须有一个Symbol.iterator方法,这个方法返回一个迭代器对象。
Iterator 接口 迭代器对象必须实现Iterator接口。这个接口定义了next()方法,该方法返回一个对象,这个对象有两个属性:value和done。value表示当前的元素值,done是一个布尔值,表示是否还有更多的元素可以迭代。
1.可迭代对象(Iterable)
一个对象如果实现了[Symbol.iterator]方法,它就是可迭代的。这个方法必须返回一个迭代器对象。常见的内置可迭代对象包括:Array,String,Map,Set,arguments对象(可通过Array.from()或扩展运算符使用),DOM的NodeList(部分浏览器)。
ts
const arr = [1, 2, 3];
console.log(arr[Symbol.iterator]);
这些对象之所以能被for...of循环遍历,正是因为它们实现了Symbol.iterator方法。
2.迭代器(Iterator)
迭代器是一个带有next()方法的对象,调用next()返回{value,done}. value:当前值(当done:true时,value可省略或为undefined) done:布尔值,表示是否遍历完成。
ts
const arr = [10, 20];
const iterator = arr[Symbol.iterator]();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());

注意:迭代器本身通常也是可迭代的(即它自己也有[Symbol.iterator()]
),这样它就可以用于for...of。
3.for...of与展开运算符的工作原理
ts
for (const item of [1, 2, 3]) {
console.log(item);
}

背后的逻辑:
- 获取
[1,2,3
][Symbol.iterator]()
- 不断调用.next()直到done:true
同理:
ts
const str = "hi";
const chars = [...str];
console.log(chars)

手动实现一个可迭代对象
ts
class Countdown {
constructor(private start: number) {}
[Symbol.iterator](): Iterator<number> {
let current = this.start;
return {
next(): { value: number; done: boolean } {
if (current < 0) {
return { value: undefined, done: true };
}
return { value: current--, done: false };
},
// 可选:支持 return() 方法用于提前终止(如 break)
return() {
console.log("迭代被中断");
return { value: undefined, done: true };
}
};
}
}
// 使用
const countdown = new Countdown(3);
for (const n of countdown) {
console.log(n);
}
生成器(Generator):简化迭代器创建
生成器函数是创建迭代器的便捷方式。使用function*
定义,内部用yield暂停执行。
ts
function* idGenerator() {
let id = 1;
while (true) {
yield id++;
}
}
const gen = idGenerator();
console.log(gen.next().value);
console.log(gen.next().value);

生成器函数返回一个生成器对象,它即是迭代器,也是可迭代对象。
你甚至可以让一个对象使用生成器作为[Symbol.iterator]
ts
const myRange = {
from: 1,
to: 5,
*[Symbol.iterator]() {
for (let i = this.from; i <= this.to; i++) {
yield i;
}
}
};
console.log([...myRange]);

迭代器协议总结:
协议:Iterable
方法:
[Symbol.iterator]():Iterator
返回值:迭代器对象
说明:表示可被遍历
协议:Iterator方法:
next():{value,done}
返回值:状态对象
说明:提供下一个值
协议:可选方法:
return?():{value,done}
返回值:状态对象
说明:处理提前退出
协议:可选方法:
throw?():{value,done}
返回值:状态对象
说明:处理异常抛出