原文地址:Iterators and Generators - Reference | TypeScript Docs

可遍历(Iterables)

如果一个对象实现了 Symbol.iterator 属性,那么它就是可遍历的。ArrayMapSetStringInt32ArrayUnit32Array 等内置类型都已经实现了 Symbol.iterator 属性。该属性是一个函数,负责返回可供遍历的值的列表。

Iterable 接口(Iterable interface)

Iterable 是一个类型,可以用来标记可遍历的类型,比如上面列出来的 ArrayMap 等。

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

for..of 声明(for..of statements)

for..of 用来遍历可遍历对象,调用它们的 Symbol.iterator 属性。下面是一个使用 for..of 遍历数组的例子:

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

for..offor..in 声明的比较(for..of vs. for..in statements)

for..of 声明和 for..in 声明都可以用来遍历列表,区别在于二者遍历的目标是不同的。for..in 返回的是被遍历对象的键,for..of 返回的是被遍历对象的数值属性的值。看一个例子:

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 主要关注的是可遍历对象的值。MapSet 等内置对象都实现了 Symbol.iterator 属性,可以用来获取它们存储的值。

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"
}

代码生成(Code generation)

以 ES5 和 ES3 为目标(Targeting ES5 and ES3)

当编译目标是 ES5 或者兼容 ES3 的引擎时,只可以遍历 Array 类型的值。当使用 for..of 遍历非数组对象时会报错,即使它实现了 Symbol.iterator 接口。

编译器会将 for..of 编译为简单的 for 循环。

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

上述代码的编译结果为:

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

以 ECMAScript 2015 或者更高版本为目标(Targeting ECMAScript2015 and higher)

当编译目标时 ECMAScript2015 或者更高版本的引擎时,编译器会将 for..of 转换为目标引擎的默认实现。