迭代器与生成器

可迭代对象

如果一个对象实现了 Symbol.iterator 属性,它就被认为是可迭代的。一些内置类型,如 Array、Map、Set、String、Int32Array、Uint32Array 等,已经实现了各自的 Symbol.iterator 属性。对象上的 Symbol.iterator 函数负责返回用于迭代的值列表。

Iterable 接口

Iterable 是一种类型,如果我们想接收上面列出的可迭代类型,就可以使用它。下面是一个例子:

ts
function toArray<X>(xs: Iterable<X>): X[] {
return [...xs]
}

for..of 语句

for..of 循环遍历一个可迭代对象,并调用该对象上的 Symbol.iterator 属性。下面是对数组使用 for..of 的简单循环:

ts
let someArray = [1, "string", false];
for (let entry of someArray) {
console.log(entry); // 1, "string", false
}

for..of 与 for..in 语句

for..of 和 for..in 语句都会遍历列表,但被迭代的值并不相同:for..in 返回被迭代对象的键列表,而 for..of 返回被迭代对象数值属性的值列表。

下面的示例演示了这一区别:

ts
let list = [4, 5, 6];
for (let i in list) {
console.log(i); // "0", "1", "2",
}
for (let i of list) {
console.log(i); // 4, 5, 6
}

另一个区别是,for..in 可作用于任何对象,它可用于检查对象上的属性;而 for..of 主要关注可迭代对象的值。像 Map 和 Set 这样的内置对象实现了 Symbol.iterator 属性,从而允许访问其中存储的值。

ts
let pets = new Set(["Cat", "Dog", "Hamster"]);
pets["species"] = "mammals";
for (let pet in pets) {
console.log(pet); // "species"
}
for (let pet of pets) {
console.log(pet); // "Cat", "Dog", "Hamster"
}

代码生成

面向 ES5

当目标为符合 ES5 的引擎时,迭代器只允许用于 Array 类型的值。对非 Array 值使用 for..of 循环会报错,即使这些非 Array 值实现了 Symbol.iterator 属性。

编译器会为 for..of 循环生成一个简单的 for 循环,例如:

ts
let numbers = [1, 2, 3];
for (let num of numbers) {
console.log(num);
}

将被生成为:

js
var numbers = [1, 2, 3];
for (var _i = 0; _i < numbers.length; _i++) {
var num = numbers[_i];
console.log(num);
}

面向 ECMAScript 2015 及更高版本

当目标为符合 ECMAScript 2015 的引擎时,编译器会生成 for..of 循环,以使用引擎内置的迭代器实现。

TypeScript 文档是一个开源项目。欢迎提交 Pull Request,帮助我们改进这些页面 ❤

最后更新:2026 年 10 月 23 日