ES2016とES2017で追加された機能について

# はじめに

[JavaScript:Everything you need to know From ES2016 to ES2019](https://inspiredwebdev.com/everything-from-es-2016-to-es-2019)を読み、本稿ではES2016とES2017 で追加された機能について、わかったことをまとめてみます。


# ES2016導入された機能

* `Array.prototype.includes()`
* べき乗演算子

## `Array.prototype.includes()`

#### 構文説明
`includes(要素数, インデックス)`メソッドは、Arrayオブジェクトの、組み込みメソッド。
第1引数で指定した要素が含まれる場合は`true`、含まれない場合は`false`を返します。
第2引数を指定することで、指定したインデックスから要素を検索します。


```JavaScript
let array = [1,2,3,4,5]


array.includes(2)//true
array.includes(6)//false

array.includes(1,0)//true
array.includes(4,3)//true

array.includes(1,3)//false


array.includes(1,-1)//false
array.includes(3,-4)//true

```

## べき乗演算子
ES2016以前は`Math.pow()`関数を使用していましたが、`**`を使用して指数演算ができるようになりました。

```JavaScript
Math.pow(2,3)//8
Math.pow(3,3)//27

2**3//8
3**3//27
```

# ES2017で導入された機能

* 文字列のパディング
* `Object.entries()`と`Object.values()`
* `Object.getOwnPropertyDescriptors()`
* プロパティ定義の末尾に`,`をつけることが可能
* `Atomics`について
* `Async`と`Await`

## 文字列のパディング
文字列の組み込みメソッド`padStart()`と`padEnd()`を使用して、
文字列の先頭(`padStart()`)もしくは末尾(`padEnd()`)に空白を挿入することができます。

```JavaScript
"hello".padStart(6);//" hello"
"hi".padEnd(6);//"hi    "

```

空白だけでなく、文字列や数値も挿入することができます。(以下、サンプルコード)

```JavaScript
"hello".padEnd(11, " World");//"hello World"
"hello".padEnd(7, " World");//"hello W"
"hello".padStart(6, "1");//"1hello"
"hello".padStart(7, "1");//"11hello"
```

## `Object.entries()`と`Object.value()`

* `Object.entries()`:1つのプロパティのキーと値を1つの配列オブジェクトにまとめて返す。


* `Object.value()`:プロパティの値を1つの配列オブジェクトにまとめて返す。


```JavaScript
let drone = {
    x:1,
    y:2,
    z:3,
    name:"drone1",
}

Object.values(drone)//[1, 2, 3, "drone1"]
Object.entries(drone)
//["x", 1]
// ["y", 2]
// ["z", 3]
// ["name", "drone1"]
```

## `Object.getOwnPropertyDescriptors()`

* `Object.getOwnPropertyDescriptors()`:オブジェクトのプロパティの記述子を返します。

```JavaScript
let drone = {
    x:1,
}

Object.getOwnPropertyDescriptors(drone)
//{x:{value: 1, writable: true, enumerable: true, configurable: true}}
```

## プロパティ定義の末尾に`,`をつけることが可能

```JavaScript
//from this
let drone = {
    x:1,
    y:2
}

//to this
let drone = {
    x:1,
    y:2,
}
```

## 共有メモリとAtomics

* アトミック操作(不可分操作)とはある処理(仮に処理Aと呼称)が次に行う処理(処理B)が開始される前に処理が終了し、
処理Aが中断されないようにすること。

### `Atomics`について

[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Atomics)では`Atomics`について次のように記述されています。

>アトミック演算は、Atomics モジュール上にインストールされます。他のグローバルオブジェクトと異なり、Atomics はコンストラクターではありません。new 演算子 を付けて使用することや Atomics オブジェクトを関数として実行することはできません。Atomics のすべてのプロパティとメソッドは静的です (例えば、Math オブジェクトの場合と同じです)。


* `Atomics.add(typedArray, index, values)`:配列内の指定したインデックスに値を追加して、追加する前の値を返します。このアトミック操作は修正された値が書き戻されるまで、他の書き込みが起こらないことを保証します。
  * `typedArray`:共有された整数のTypedArray。`Int8Array`、`Uint8Array`、`Int16Array`、`Uint16Array`、`Int32Array`、`Uint32Array` のいずれか。

* `Atomic.sub(typedArray, index, values)`:配列内の指定したインデックスに値を取り除き、取り除く前の値を返します。

* `Atomic.load(typedArray, index)`:配列中の指定した位置(インデックス)の値を返します。

* `Atomics.store(typedArray, index, value)`:指定した位置に指定した値を保存して、その値を返します。

```JavaScript
const buffer = new SharedArrayBuffer(16);
const uint8 = new Uint8Array(buffer);
uint8[0] = 3

//Atomic.add()
console.log(Atomics.add(uint8, 0, 2))//3

console.log(Atomics.add(uint8, 0, 1))//5

//Atomic.load()
console.log(Atomics.load(uint8,0));
```

#### `Atomic.and()`、`Atomic.or()`、`Atomic.xor()`

これらの3つメソッドはビット単位のAND、OR、XOR演算子に対応します。

## `Async`と`Await`

### `Async`と`Await`の特徴

* `async function`により非同期処理を行うことができます。

* `async function`はPromiseオブジェクトを返します。

* `await`は非同期関数内のみで使用することができます。

* `await`を定義することにより、定義されたコードの処理が終了するまで、次の処理に進みません。

* 例外処理では、`.catch()`メソッドを使用することにより、エラーをキャッチできます。(ex.`asyncFunc().catch(console.log)`)

* `Promise`構文で非同期処理を記述するよりも、簡単に書けます。(以下、サンプルコード)

```JavaScript
//Promiseで書いた場合
function resolveSample(value) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(value);
        }, 2000);
    })
}

function sample() {
    let result = 0;

    return resolveSample(5)
        .then(val => {
            result += val;
            return resolveSample(10);
        })
        .then(val => {
            result *= val;
            return resolveSample(20);
        })
        .then(val => {
            result += val;
            return result;
        });
}

sample().then((v) => {
    console.log(v); //70
});


//Async,Awaitを使用した場合
function resolveSample(value){
    return new Promise(resolve =>{
        setTimeout(() => {
            resolve(value)
        }, 2000)
    })
}

async function sample(){
    return await resolveSample(5) * await resolveSample(10) + resolveSample(20);
}

sample().then((v) => {
    console.log(v); //70
});
```

# 参考文献
* [JavaScript:Everything you need to know From ES2016 to ES2019](https://inspiredwebdev.com/everything-from-es-2016-to-es-2019)
* [MDN](https://developer.mozilla.org/ja/)