ES2016 / ES2017で実装される機能まとめ

何番煎じだよ！と言われそうだけど、
ES2016とかES2017で実装される機能まとめ。


## 追加される機能

なんか色々ある。一個づつやったるで。

### ES2016
* Array.prototype.includes
* Exponentiation Operator

### ES2017
* Object.values/Object.entries
* String padding
* Object.getOwnPropertyDescriptors
* Trailing commas in function parameter lists and calls
* Async Functions
* Shared memory and atomics

https://github.com/tc39/proposals/blob/master/finished-proposals.md

## Array.prototype.includes

要素が配列の中に含まれているかを判定する。
`indexOf()`とか使わなくていいし、boolean型で返ってくるのはすごく素敵。

```javascript
// 構文
const boolean = array.includes(searchElement[, fromIndex]);

const arr = ['a', 'b', 'c'];

arr.includes('a'); // true
arr.includes('b'); // true
arr.includes('c'); // true
arr.includes('d'); // false

// 第二引数:fromIndexで何番目かを指定可能
arr.includes('a', 0); // true
arr.includes('a', 1); // false

// fromIndexは負の値の場合、配列の末尾から探す
arr.includes('c', -1); // true

// Indexは計算される
// 計算された値が0未満の場合、配列の全体を計算する

// arr.length = 3
// fromIndex = -100
// 3 - (-100) = -97
arr.includes('a', -100); // true
arr.includes('b', -100); // true
arr.includes('c', -100); // true

// 対象が配列じゃない？ callしちまえばええんや！
(function(){
	[].includes.call(arguments, 'a'); // true
	[].includes.call(arguments, 'd'); // false
})('a', 'b', 'c')
```

ちなみに`indexOf()`。これはキモかった。

```javascript
const arr = ['a', 'b', 'c'];

arr.indexOf('a') >= -1 // true
```

## Exponentiation Operator
n乗とか計算できるようになる。
プロジェクトによっては重宝するのかな？多分。

```javascript
2 ** 2 // 4
2 ** 3 // 8
```

## Object.values/Object.entries

`Object.keys`と立ち位置的には同じ印象。
対象のObjectを走査して、取得した値を配列で返す。
取得してくる値は下の表を参照。

| メソッド | 取得する値 | 
|:-----------|:------------|
| Object.keys|キー|
| Object.values|値|
| Object.entries|キーと値のセット|

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/values
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/entries

```javascript
const obj = {
	name: 'pikotarou',
	color: 'gold'
};

Object.values(obj); // ["pikotarou", "gold"]
Object.entries(obj); // [["name", "pikotarou"], ["color", "gold"]]
```
ここで列挙されるのは`hasOwnProperty()`と`propertyIsEnumerable()`が`true`になる値が対象になっている。

## String padding
文字埋めのための機能が追加される。
日付などで0を埋めるときとかに使うのかな。
記事を書いている現在（2017/3/5）ではfirefoxしかサポートされていない模様。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/padStart

```javascript
// 構文
str.padStart(targetLength [, padString])
str.padEnd(targetLength [, padString])

'abc'.padStart(10);         // "       abc"
'abc'.padStart(10, "foo");  // "foofoofabc"
'abc'.padStart(6,"123465"); // "123abc"
'abc'.padEnd(10);         // "abc       "
'abc'.padEnd(10, "foo");  // "abcfoofoof"
'abc'.padEnd(6,"123465"); // "abc123"
```

## Object.getOwnPropertyDescriptors

javascriptのオブジェクトにおけるプロパティには属性というものが設定されている。
この属性値はそれぞれ以下の6種類が存在している。

|属性|意味|型|
|:-----------|:------------||:------------|
|Writable|値を書き込み可能か|boolean|
|Enumerable|列挙可能か（for-inとかで対象にするか）|boolean|
|Configurable|Descriptorを変更可能か|boolean|
|Value|値|any|
|Get|Getter|function|
|Set|Setter|function|

ES5で実装された`Object.defineProperty()`はこれらを設定することができるメソッドだった。
`Object.getOwnPropertyDescriptor()`で対象の値がどのような状態だったのか確認することができた。

```javascript
Object.defineProperty(document, 'myProperty', {
  writable: true,
  enumerable: true,
});

Object.getOwnPropertyDescriptor(document, 'myProperty');
// {
//     value: undefined,
//     writable: true,
//     enumerable: true,
//     configurable: false
// }
```

前置きが長くなったけど、
今回追加されるのは`Object.getOwnPropertyDescriptor()`を複数要素に対応したverという感じ。
名前も複数形でsがついただけ。`Object.getOwnPropertyDescriptors()`。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors

```javascript
const obj = {
    name: 'pikotarou',
    color: 'gold'
};

Object.getOwnPropertyDescriptor(obj, "name");
// {
//    configurable: true ,
//    enumerable: true,
//    value: "pikotarou",
//    writable: true
// }

Object.getOwnPropertyDescriptors(obj);
// {
//     "name": {
//         configurable: true ,
//         enumerable: true,
//         value: "pikotarou",
//         writable: true
//     },
//     "color": {
//         configurable: true,
//         enumerable: true,
//         value: "gold",
//         writable: true
//     }
// }
```

## Trailing commas in function parameter lists and calls
引数の最後にカンマをつけたとしてもエラーにならなくなる。
私のようなコピペおじさんには優しい。

```javascript
function myFunc(
    param1,
    param2, // これもOK
) { /* ... */ };

myFunc(
    'foo',
    'bar', // これもOK
);
```

## Async Functions
これは注目されていたからみんな知ってそう。
いわゆる非同期処理を同期的に書くことができるようになる。
node.jsはv7.6.0でasync/awaitをサポートするようになった。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/async_function

非同期処理に関してはこのあたりの記事とか分かりやすかった。
https://sbfl.net/blog/2016/07/13/simplifying-async-code-with-promise-and-async-await/
http://qiita.com/gaogao_9/items/5417d01b4641357900c7

### async / await
覚えるのはこの2つ。
`await`はPromiseの完了を待ち、その結果を展開する。
`await`がつけられたPromiseは終了するまでコードの実行は先に進まなくなる。
つまり、非同期処理を同期的に実行できる。

そして`await`は`async`がつけられた関数の中でしか使用できない。
さらに`async`がついた関数はPromiseを返すため、`then()`や`catch()`もそのままチェーンできる。
実際にコードを書くと以下のようになる。

```javascript
(async () => {
    console.log('async start');
    await new Promise((resolve) => {
    	setTimeout(resolve, 3000);
    });
    console.log('async end'); // 3000ms後に実行される
})().catch((error) => {
	console.log(error);
});
```

実際これで非同期処理を書いたところ、可読性が著しく上がるため非常に有用性があると感じた。

## Shared memory and atomics
うーん、知識不足で全く追えていない。
何をするための機能かすらまだ理解できていないので追って勉強したい。
このへんとかかな。
http://www.2ality.com/2017/01/shared-array-buffer.html

#### 2018.04.12 追記
@yosuke_furukawa さんの記事が大変参考になりました

>SharedMemory と Atomic API について
https://qiita.com/yosuke_furukawa/items/923f8d40c451713dfbd3

## まとめ
いくつか追加される機能をざっくり紹介してみた。
個人的に好きなのは`Array.prototype.includes`と`Async Functions`。

記事の中で間違っている部分などありましたらご指摘いただけると助かります。