Skip to content
赞助商
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待

迭代器与生成器 ​

可迭代对象 ​

如果一个对象具有 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 类型的值。 在非数组值上使用 for..of 循环是错误的,即使这些非数组值实现了 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 循环,以针对引擎内置的迭代器实现。