mirror of
https://github.com/gnu4cn/ts-learnings.git
synced 2024-12-26 21:00:10 +08:00
83 lines
2.9 KiB
Markdown
83 lines
2.9 KiB
Markdown
# 迭代器与生成器
|
||
|
||
**Iterators and Generators**
|
||
|
||
## 可迭代对象(Iterables)
|
||
|
||
在对象有着`Symbol.iterator`属性时,其就被认为是可迭代的。一些内建类型,比如`Array`、`Map`、`Set`、`String`、`Int32Array`、`Uint32Array`等,都已经有着其已实现的`Symbol.iterator`属性。对象上的`Symbol.iterator`函数,赋值返回要迭代的值的清单(`Symbol.iterator` function on an object is responsible for returning the list of values to iterate on)。
|
||
|
||
### `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..of`与`for..in`语句都是对清单进行迭代;但所迭代的值却是不同的,`for..in`返回的是所迭代对象的 *键* 的清单,而`for..of`则是返回的所迭代对象数值属性的 *值* 的清单(Both `for..of` and `for..in` statements iterate over lists; the values iterated on are differenct though, `for..in` returns a list of *keys* on the object being iterated, whereas `for..of` returns a list of *values* of the numeric properties of the object being interatd)。
|
||
|
||
```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`属性的内建对象,才允许对存储值的访问(Built-in objects like `Map` and `Set` implement `Symbol.iterator` property allowing access to stored values)。
|
||
|
||
```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"
|
||
}
|
||
```
|
||
|
||
## 关于代码生成(Code generation)
|
||
|
||
### 目标代码为ES5及ES3
|
||
|
||
在生成目标代码为ES5或ES3时,只允许在`Array`类型上使用迭代器。就算非数组值实现了`Symbol.iterator`属性, 在它们上使用`for..of`循环都是错误的。
|
||
|
||
编译器将为`for..of`循环生成一个简单的`for`循环,例如:
|
||
|
||
```typescript
|
||
let numbers = [1, 2, 3];
|
||
|
||
for (let num of numbers) {
|
||
console.log(num);
|
||
}
|
||
```
|
||
|
||
将生成如下代码:
|
||
|
||
```javascript
|
||
var numbers = [1, 2, 3];
|
||
|
||
for (var _i = 0; _i < numbers.length; _i++) {
|
||
var num = numbers[_i];
|
||
console.log(_i);
|
||
}
|
||
```
|
||
|
||
### 目标代码为ECMAScript2015或更高版本时
|
||
|
||
在以兼容ECMAScript2015引擎为目标时,编译器将生成`for..of`循环,从而以引擎中的内建迭代器实现为目标。
|