2年ぐらいJavaScriptから離れていた人に贈るES6対応表

この記事は[Tech-Circle Hands on Advent Calendar 2016](http://qiita.com/advent-calendar/2016/techcircle)の2日目の記事です。

昨日は[tominaga443](http://qiita.com/tominaga443)さんの[パワポでつくるスマホアプリ: CanvasFlipでインタラクティブなプロトタイピング](http://qiita.com/tominaga443/items/376993e707314f5d9dae)でした。
引き続きフロントエンド週間ですが、今日はJavaScript行ってみましょう。

----

「JavaScript? うん、まぁ最近書いてないけど、ある程度は読み書きできるよ」
---------------------------------------------------
とか言っていたのもつかの間、新しめのコードを見てみるとES6(ES2015)、ES2016で追加された新しい記法に打ちのめされたりします。

ReactやらReduxやら、新しい技術はどんどん出てきますが、学ぶ際に記法で嵌っているとコアな部分に集中できないので、まずは新しい記法に慣れてしまいましょう。
わかってしまえば単なる便利記法なので難しくないです。

なお、React/Reduxのコードを読むうえで出会った箇所が主なため、一部の例はBabelによる次期ESの先取りとなります。
それでは、ググりづらい記号系をメインに進めていきましょう。


連想配列の省略表記
-------------------------------
まずは手軽な物から。
keyとvalueが同名の場合、省略が可能になりました。

```js:JavaScript
var sample = 42
{ sample: sample }  // { sample: 42 }
```


```js:ES6
const sample = 42
{ sample }          // { sample: 42 }
```

配列からの展開
------------------------------
配列の値を変数に代入する際、まとめて代入ができるようになりました。

```javascript:JavaScript
var list = [1, 2, 3]
var a = list[0]
var b = list[1]
```

```js:ES6
const list = [1, 2, 3]
const [a, b] = list
```

関数から複数返り値を受け取ったりも。

```js:ES6
const [result, isFinished] = execute()
```


連想配列からの展開
------------------------------
同様に連想配列にも使えます。配列からの代入よりはこっちの方がメジャーかも。
Reactのコードを読み書きしていると、`this.props`からの代入でよくお世話になりますね。

```javascript:JavaScript
var dictionary = {
  url: 'http://www.example.com',
  method: 'GET'
}

var url = dictionary.url
var method = dictionary.method
```

```javascript:ES6
const dictionary = {
  url: 'http://www.example.com',
  method: 'GET'
}

const { url, method } = dictionary
```

### 深い階層からも取れます
```javascript:ES6
const dictionary = {
  url: 'http://www.example.com',
  method: 'GET',
  parameters: {
    name: 'Sheile'
  }
}

const { url, method, parameters: { name } } = dictionary
console.log(name)   // Sheile
```

ただし、この場合`parameters`は取れないので注意。

配列の展開
--------------------------------
`...`表記で配列の展開ができるようになりました。

```js:JavaScript
var list = [1, 2, 3]
Math.max(list)              // NaN これはダメ
Math.max.apply(null, list)  // 3
```

```js:ES6
const list = [1, 2, 3]
Math.max(...list)           // 3
```

### 配列の結合
配列の途中で`...`を使うことで配列の結合、挿入が手軽にできます。

```js:ES6
const list = [2, 3, 4]
[1, ...list, 5]        //  [1, 2, 3, 4, 5]
```

連想配列の展開
---------------------------------
前項の`...`演算子は連想配列にも適用できる……ようになる予定です。
現在Stage3なので仕様は確定していますが、いま使うにはBabelなどのトランスパイラが必要になります。

ただ、Reduxのreducerを書いているとすごく多用するため、ここで紹介。
reducerでの使い方は既存のオブジェクトを活かしつつ、一部を書き換える用途なので、JavaScriptで言うと`lodash.assign`、ES2015で言うと`Object.assign`の代替ですね。

＃Stage3って何？という方はこちらの記事がわかりやすいです
[ES2016の追加機能が決定、あるいはES7言うな問題](http://teppeis.hatenablog.com/entry/2016/01/es2016-feature-freeze)

```js:JavaScript
var _ = require('lodash')
var state = { key: 'value', isFetching: true }
var newState = _.assign({}, state, { isFetching: false })
// { key: 'value', isFetching: false }
```

```js:ES6+Babel
const state = { key: 'value', isFetching: true }
const newState = {
  ...state,
  isFetching: false
}   // { key: 'value', isFetching: false }
```

アロー関数(`=>`)による関数定義
--------------------------------
AltJS系ではおなじみ、アロー関数による関数定義もできるようになりました。

```javascript:Javascript
function output(key, value) {
  console.log(key)
  console.log(value)
}
```

```javascript:ES6
output = (key, value) => {
  console.log(key)
  console.log(value)
}
```

見比べてみると対して違いは無いと思います。
`function`がなくなって、匿名関数を変数に代入するようになっています。

### 記法の省略
前項の例だとあまり違いがありませんが、アロー関数は条件次第で記述の省略が可能です。
`Array#map`など、引数に関数をとる場合はこの省略記法が良く使われるので慣れておきましょう。

```javascript:JavaScript
[1, 2, 3].map(function (n) {
   return n * 2
})
//  [2, 4, 6]
```

```javascript:ES6
//	引数1つなら (n) ではなく n でOK
//	関数内が単一式ならば {} や return は不要
[1, 2, 3].map(n => n * 2)
```

### 高階関数
では、ちょっとややこしい例を見てみましょう。

```javascript:ES6
fetchData = token => dispatch => {
  /* 省略 */
}
```

さて、これをfunction表記に戻すと？
＃読み方に慣れた人は答えを見る前に考えてみても良いです

```javascript:JavaScript
function fetchData(token) {
  return function(dispatch) {
    /* 省略 */
  }
}
```

はい、こうなります。あってました？

### thisの束縛
CoffeeScriptで`->`と`=>`を使っていた人にはお馴染みですが、アロー関数の場合、定義時のスコープでthisが束縛されます。
`class`定義内の関数はこっちの方が使い勝手が良いですね。

```javascript
$(function() {
  function handleClick1() {
    console.log(this)     // <button>
  }

  handleClick2 = () => {
    console.log(this)     // document
  }

  $('button#button1').click(handleClick1)
  $('button#button2').click(handleClick2)
})
```

```javascript:ES6
handleClick = () => {
  console.log(this)
}
```

```javascript:JavaScript
that = this
function handleClick() {
  console.log(that)
}
```

最後に
----------------
明日は色々な便利Chrome拡張を作っている[tksugimoto](http://qiita.com/tksugimoto)さんです。