ES2019で追加される(かもな)最新機能ピックアップ

2015年に ES2015 がリリースされてから、個人的に EcmaScript の毎年の新機能のリリースがとても楽しみになりました。
そして来年には ES2019 のリリースが控えています。

そこでこの記事では、執筆時点で ECMAScript proposals で Stage 3 の段階にあるものの中で個人的に興味があるものをいくつかピックアップします。
( ES2019 に確実に含まれることを保証するものではありません)

# BigInt

JavaScript では取り扱える整数値の最大が決まっています。
それは `Number.MAX_SAFE_INTEGER` で取得することができます。この値は `2の53乗 - 1` の値になります。

```javascript
const x = Number.MAX_SAFE_INTEGER

console.log(x === 2 ** 53 - 1) // true
console.log(x) // 9007199254740991
console.log(x + 1) // 9007199254740992
console.log(x + 2) // 9007199254740992
```

見てわかる通り、 `9007199254740991` よりも大きい整数は正しく扱うことができません。
それを扱えるようにしたのが `BigInt` です。

`BigInt` は整数の最後にnを加えるか、コンストラクタを呼び出すことで作成できます。

```javascript
const x = 9007199254740991n
const y = BigInt(9007199254740991)
const z = BigInt('9007199254740991') // string も渡せる

console.log(x === y) // true
console.log(x === z) // true
```

`BigInt` は `Number` と同様に演算ができます。
しかし `/` だけは `Number` での計算とは違い、計算結果の小数点を丸めてしまいます。

```javascript
const x = BigInt(Number.MAX_SAFE_INTEGER)

console.log(x) // 9007199254740991n
console.log(x + 2n) // 9007199254740993n
console.log(x - 2n) // 9007199254740989n
console.log(x * 2n) // 18014398509481982n
console.log(x % 10n) // 1n
console.log(x ** 2n) // 81129638414606663681390495662081n

console.log(x / 1000000000000000n) // 9n
```

`Number` と比較した際の挙動など、細かな仕様は以下で確認できます。
[GitHub - tc39/proposal-bigint: Arbitrary precision integers in JavaScript](https://github.com/tc39/proposal-bigint)

## Array.prototype.{flat,flatMap}

Array のメソッドとして、 `flat` と `flatMap` が追加されました。

### flat

ネストされた配列を結合することができます。
どの深さまでのネストに対応するのかを引数で指定することができます。デフォルトは `1` です。

```javascript
const arr1 = [1, 2, [3, 4]]
console.log(arr1.flat()) // [1, 2, 3, 4]

const arr2 = [1, 2, [3, 4, [5, 6]]]
console.log(arr2.flat()) // [1, 2, 3, 4, [5, 6]]

console.log(arr2.flat(2)) // [1, 2, 3, 4, 5, 6]
```

便利。

### flatMap

配列に対して `Array.prototype.map` を行って返された配列に `Array.prototype.flat` を行うイメージです。
しかし `flat` を行う際のネストのレベルは1階層分のみです。

```javascript
const arr = [1, 2, 3, 4]

function callback(x) {
  return [x * 2]
}

console.log(arr.map(callback)) // [[2], [4], [6], [8]]
console.log(arr.flatMap(callback)) // [2, 4, 6, 8]

// flat と違い対応できるネストの深さは指定できず、1段階までです
console.log(arr.flatMap(x => [[x * 2]])) // [[2], [4], [6], [8]]
```

すごく便利。

## String.prototype.{trimStart,trimEnd}

String のメソッドとして、 `trimStart` と `trimEnd` が追加されました。
以前からあった `String.prototype.trim` は文字列の前後の空白を削除するメソッドでしたが、今後は前を削除するのか後ろを削除するのかを選べるようになります。

```javascript
const str = ' hoge '

console.log(str.trim()) // "hoge"
console.log(str.trimStart()) // "hoge "
console.log(str.trimEnd()) // " hoge"
```

あまり前のスペースだけ、もしくは後ろのスペースだけを削除したい実例が思い浮かばなかったのですが、なんにせよ対応できる幅が増えるのは良いことですね。

## Object.fromEntries

`Object.entries` の逆バージョンです。
`Object.entries` が渡したオブジェクトをキーバリューの配列を返すのとは逆に、キーバリューの配列を渡すとそれをオブジェクトに変えてくれます。

```javascript
const obj = Object.fromEntries([['a', 0], ['b', 1]])

console.log(obj) // { a: 0, b: 1 }
```

個人的に `Object.entries` は多用するので、きっと `Object.fromEntries` も多用するのでしょう、きっと・・・。

細かな仕様は以下で確認できます。
[GitHub - tc39/proposal-object-from-entries: TC39 proposal for Object.fromEntries](https://github.com/tc39/proposal-object-from-entries)

## import()

いわゆる dynamic import です。
外部モジュールを動的に読み込むことができるようになります。

Code Splitting などですでに使用している方は多いかと思いますが、それが ES2019 では標準で使えるようになるかもしれません。

この import 文は Promise を返します。

```javascript
const filePath = 'modules/func'

import(`./${filePath}.js`)
  .then(module => {
    console.log(module)
  })
  .catch(err => {
    console.error(err)
  })
```

他の細かな仕様は以下で確認できます。
[GitHub - tc39/proposal-dynamic-import: import() proposal for JavaScript](https://github.com/tc39/proposal-dynamic-import)

## おわり

いくつか解説しましたが、現時点での ECMAScript proposals の Stage 3 は他にもまだまだあります。
全て見てみたいという方は `tc39/proposals` のリポジトリを見てみてください。

[GitHub - tc39/proposals: Tracking ECMAScript Proposals](https://github.com/tc39/proposals)