Skip to content
0

TypeScript Office - 迭代器和生成器

遍历

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

Iterable 接口

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

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

for..of 声明

for...of 在一个可迭代对象上循环,调用对象上的 Symbol.iterator 属性。下面是一个关于数组的简单 for.of 循环。

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

for..of 与 for..in 声明

for...offor...in 语句都是在列表上进行迭代;但迭代的值是不同的,for...in 返回被迭代对象的键值列表,而 for...of 返回被迭代对象的数字属性值列表。

这里有一个例子可以证明这种区别:

typescript
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` 属性,允许访问存储的值。

typescript
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 和 ES3

当针对 ES5 或 ES3 兼容的引擎时,迭代器只允许在 Array 类型的值上使用。在非数组值上使用 for...of 循环是一个错误,即使这些非数组值实现了 Symbol.iterator 属性。

例如,编译器将为 for... 的循环生成一个简单的 for 循环。

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

将被生成为:

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

ECMAScript 2015 和 更高版本

当针对 ECMAScipt 2015 兼容的引擎时,编译器将生成 for...of 循环,以针对引擎中的内置迭代器实现。

最近更新