5分でわかる「今更だけどES6(ES2015)ってなに？」

個人的なおさらい用です。

# ECMAScript 6 とは

Ecma International によって標準化された言語仕様です。JavaScript は基本的にこの ECMAScript の仕様を元に実装されています。

# 新たに提供された主な仕様
- `Class` 命令文によるクラス定義が可能になった
- `import/export` 命令によるコードのモジュール化
- 関数構文の改善（引数のデフォルト値、可変長引数、アロー関数など）
- `let/const` 命令によるブロックスコープの導入
- `For...of`
- イテレーター/ジェネレーターによる列挙可能なオブジェクトの操作が可能に
- `Promise` 、`Map/Set`、 `Proxy` などの組み込みオブジェクトを追加
- `String/Number/Array/Object` などの既存組み込みオブジェクトの拡充など


#すぐ使える便利な機能

## 文字列リテラルへの変数/改行の埋め込み

バッククォートで文字列を括ることで可能になります

```javascript
`string text`

`string text line 1
 string text line 2`

`string text ${expression} string text`

tag `string text ${expression} string text`
```

## 分割代入（destructuring assignment）
分割代入とは、配列/オブジェクトを分解し、その要素/プロパティを個々の変数に展開するための構文です。

配列要素を順に変数 `hoge/foo` に割り当てます。

```javascript
let [hoge, foo] = [15, 12]
```

スプレッド演算子を使うことで、残りの要素をまとめて配列として取り出すこともできます。

```javascript
let [hoge, foo, ...other] = [10, 20, 30, 40, 50]
console.log(other) // [30, 40, 50]
```

オブジェクトのプロパティに割り当てることも。

```javascript
let {hoge, foo} = {
  hoge: 'ほげ',
  foo: 'ふー'
}
```

入れ子になったプロパティを割り当てる場合は以下のようにします。

```javascript

let data = {
  hoge: 'ほげ',
  foo: {
    piyo: 'ぴよ',
    bar: 'ばー'
  }
}

let {  hoge, foo, foo: {piyo, bar}} = data;
```

プロパティを異なる名前の変数に割り当てたい場合は以下のように。

```javascript

let {hoge: x, foo} = {hoge: ‘ほげ’, foo: ‘ふー’};
console.log(x) // ほげ
```

※デフォルト値を用意しておくこともできます。

## スプレッド演算子
スプレッド演算子は配列やオブジェクトの要素を展開する演算子です。
配列を複製してから要素を追加して新しい配列を生成し、それをマージするなどの処理を簡潔に書くことができます。
構文は以下です。

```javascript
// ピリオドを3つ
...hoge
``` 
---
詳しい説明は以下の記事が参考になります。
[JSのスプレッド演算子を理解する](https://qiita.com/Nossa/items/e6f503cbb95c8e6967f8)
[【JavaScript】スプレッド構文の便利な使い方まとめ](https://qiita.com/akisx/items/682a4283c13fe336c547)

## アロー関数
ES6で追加された構文のひとつ、アロー関数式には2つの特徴があります。

- 関数リテラルをシンプルに記述できる。
- アロー関数内での `this` はアロー関数が宣言された場所が `this` になる。

### 関数リテラルをシンプルに記述できる
```javascript
// 今までの関数
let name = function(x) {
  ...statement...
}

// アロー関数式
let name = (x) => {
  ...statement...
}

// アロー関数式が一文のみ
let name = (x) => ...statement...

// 引数もひとつの場合
let name = x => ...statement...

// 引数がない場合
let name =()=> ...statement...
```
非常にシンプルに記述できるようになっています。

### this の扱い
これまでの JavaScript では、関数の中で `this` を使うと呼び出し元のオブジェクトが参照されます。つまり、呼び出される関数によって中身が変わってしまうのです。
しかしアロー関数を使った場合では `this` は **アロー関数が宣言された場所** で固定されます。

## Promise
`Promise` は非同期処理を簡便にするオブジェクトです。

`Promise` コンストラクターは、`resolve/reject` という2個の関数を受け取るので、非同期処理ではこれらの関数を利用して、成功（`resolve`）/失敗（`reject`）を通知します。
その結果を受け取るのは `then(success, failure)` メソッドです。
引数 `success` / `failure` はそれぞれ `resolve` / `reject` 関数で指定された引数の内容を受け取って成功/失敗時の処理を実施します。

※ 現在は非同期処理を実装する場合は、より簡潔に記述できる ES7 の `await/async` が推奨されています。 babel などのトランスパイラを噛ませればもう使えますので、ES6 でこういうの出てたんだな～くらいに思って `await/async` を学習するほうがよさそうです。

こちらがわかりやすいです。
[async/await 入門（JavaScript）](https://qiita.com/soarflat/items/1a9613e023200bbebcb3)

## Map/Set
ES6 では Map オブジェクトと Set オブジェクトというデータ構造が追加されました。

### Map
`key/prop` のセットでデータを管理するオブジェクトです。
型がもてるのが特徴のひとつで、 `size` プロパティでサイズを簡単に取得できたり、反復処理を行うのに便利です。

```javascript
let m = new Map();
m.set(‘hoge’, 'ほげ')
```

これで簡単にマップのキーや値を列挙したり、順番に処理したりすることができる。

### 一意な値を管理する場合は Set を使う
`Set` オブジェクトは重複した値は無視した一意なデータのコレクションを扱うことができます。
`Map` のように key で管理されないデータを格納します。
あらゆる型で一意の値を格納できるため、例えば API からデータを受け取ったときにユニーク ID はいくつあるか、といったシーンで便利そうですね。

```javascript
let s = new Set();
s.add(2);
```

# まとめ
ここまでお読みいただきありがとうございます！
個人的には今後の JavaScript を基本的に TypeScrpt で記述することになると思います。
そのために、TypeScript で使っている機能が ES6 ではどの程度実装されているのか知ることは重要なのかな、と感じました。

誤りや認識の違いなどがありましたらご指摘いただけると助かります！:bow: