TypeScript Office - 迭代器和生成器
# 遍历
如果一个对象有 Symbol.iterator 属性的实现,它就被认为是可迭代的。一些内置类型,如 Array、Map、Set、String、Int32Array、Uint32Array 等,已经实现了它们的 Symbol.iterator
属性。对象上的 Symbol.iterator
函数负责返回要迭代的值的列表。
# Iterable 接口
Iterable 是一个我们可以使用的类型,如果我们想接收上面列出的可迭代的类型。下面是一个例子:
function toArray<X>(xs: Iterable<X>): X[] {
return [...xs]
}
1
2
3
2
3
# for..of 声明
for...of
在一个可迭代对象上循环,调用对象上的 Symbol.iterator
属性。下面是一个关于数组的简单 for.of
循环。
let someArray = [1, "string", false];
for (let entry of someArray) {
console.log(entry); // 1, "string", false
}
1
2
3
4
2
3
4
# for..of 与 for..in 声明
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
}
1
2
3
4
5
6
7
2
3
4
5
6
7
另一个区别是 for...in
对任何对象进行操作;它作为一种检查该对象上的属性的方法。另一方面,for...of 主要对可迭代对象的值感兴趣。像 Map 和 Set 这样的内置对象实现了
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"
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 代码生成
# 生成目标 ES5 和 ES3
当针对 ES5 或 ES3 兼容的引擎时,迭代器只允许在 Array 类型的值上使用。在非数组值上使用 for...of
循环是一个错误,即使这些非数组值实现了 Symbol.iterator
属性。
例如,编译器将为 for...
的循环生成一个简单的 for 循环。
let numbers = [1, 2, 3];
for (let num of numbers) {
console.log(num);
}
1
2
3
4
2
3
4
将被生成为:
var numbers = [1, 2, 3];
for (var _i = 0; _i < numbers.length; _i++) {
var num = numbers[_i];
console.log(num);
}
1
2
3
4
5
2
3
4
5
# ECMAScript 2015 和 更高版本
当针对 ECMAScipt 2015 兼容的引擎时,编译器将生成 for...of
循环,以针对引擎中的内置迭代器实现。
编辑此页 (opens new window)
更新时间: 2023/09/18, 16:34:13