TypeScript Handbook を読む (12. Iterators and Generators)

[TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/basic-types.html) を読み進めていく第十二回目。

1. [Basic Types](http://qiita.com/murank/items/9c1f633545842c953947)
1. [Variable Declarations](http://qiita.com/murank/items/913f1c1e4e725047436c)
1. [Interfaces](http://qiita.com/murank/items/553276c3dc2eec9bfe47)
1. [Classes](http://qiita.com/murank/items/7e8f15225bc8259e9bf3)
1. [Functions](http://qiita.com/murank/items/e310ce68ed5a0058d42d)
1. [Generics](http://qiita.com/murank/items/144b686d34fd433a97a3)
1. [Enums](http://qiita.com/murank/items/cc487562b21bae3728ba)
1. [Type Inference](http://qiita.com/murank/items/e67ad7426020321228e9)
1. [Type Compatibility](http://qiita.com/murank/items/e06efb0615294a6826e3)
1. [Advanced Types](http://qiita.com/murank/items/bc1776efbecbd2120d94)
1. [Symbols](http://qiita.com/murank/items/04b3b31caa677750f240)
1. Iterators and Generators (今ココ)
1. [Modules](http://qiita.com/murank/items/0fc4e059be8ea5e1c274)
1. [Namespaces](http://qiita.com/murank/items/0dfad4a0bb91aaa6c97b)
1. [Namespaces and Modules](http://qiita.com/murank/items/0be1978a3515fc76e7ba)
1. [Module Resolution](http://qiita.com/murank/items/5f11466474d49498bbd5)
1. [Declaration Merging](http://qiita.com/murank/items/ec90ba04edab1ea3718e)
1. [JSX](http://qiita.com/murank/items/90164aa9a3bed3c49a80)
1. [Decorators](https://qiita.com/murank/items/580e34883e0832ca7aed)
1. [Mixins](https://qiita.com/murank/items/e77ad8359ed1fd82822d)
1. [Triple-Slash Directives](https://qiita.com/murank/items/faff57883338ebdeda12)
1. [Type Checking JavaScript Files](https://qiita.com/murank/items/588eaddfe8af59914658)


# Iterators and Generators
[原文](https://www.typescriptlang.org/docs/handbook/iterators-and-generators.html)

## Iterables

[`Symbol.iterator`](http://qiita.com/murank/items/04b3b31caa677750f240#symboliterator) プロパティを持つオブジェクトは反復可能なオブジェクトとして扱われます。

### `for..of` statements
`for...of` はオブジェクトの持つ `Symbol.iterator` プロパティを使用してループを行います。

```ts:TypeScript
let someArray = [1, "string", false];

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


### `for..of` vs. `for..in` statements
`for..of` と `for..in` はともにリストをループしますが、`for..in` はオブジェクトの *キー* のリストを返却するのに対し、`for..of` は数値インデックスで参照できる *値* を返却する点が異なります。

```ts: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` を持っています。

```ts: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
#### Targeting ES5 and ES3
ES5 または ES3 を対象としている場合、反復対象とできるのは  `Array` のみです。
それ以外の型を対象とした場合、それが `Symbol.iterator` を実装していたとしてもエラーとなります。

この時、コンパイラは `for..of` から単純な `for` ループを生成します。

```ts:TypeScript
let numbers = [1, 2, 3];
for (let num of numbers) {
    console.log(num);
}
```
```js:JavaScript
var numbers = [1, 2, 3];
for (var _i = 0; _i < numbers.length; _i++) {
    var num = numbers[_i];
    console.log(num);
}
```

#### Targeting ECMAScript 2015 and higher
ECMAScipt 2015 を対象としている場合、ネイティブの `for..of` を使用するコードが生成されます。