ES2021
Ecma International approves new standards - Ecma International
6月22日、正式にES2021が仕様として承認され下記5つの機能が追加された。ブラウザも対応しておりモダンブラウザ(Chrome/Firefox/Edge/Safari)でES2021の全機能が使える。
Numeric separator
例えば100000000という数字を見た時、それが1億なのか1千万なのかわかりにくい。Numeric separatorを使うとアンダースコア(_)の使うことで数字を区切ることができ、可読性が格段に上がる。
const tenMillion = 10_000_000 // 1千万
const hundredMillion = 100_000_000 // 1億
console.log(1_000n.toString()) // 1000
console.log(1_000 * 2) // 2000
console.log(`${20_000 * 2 - 24_050} euro`) // 15950 euro
アンダースコア(_)で区切られていてもあくまで数値なので、通常通り四則演算も可能。
Logical assignment operators
ES2021では、??=、||=、&&= の3つのLogical assignment operatorが追加された。 例を見る前にそれぞれのoperatorのおさらいをしておく。
||
|| は左の値がFalsyの場合、右側の値が評価される
const animal = ''
const pet = animal || 'cat'
console.log(pet) // cat
??
?? は左の値がNullish(nullもしくはundefined)の場合にのみ、右側の値が評価される。
const animal1 = undefined
const animal2 = '' // falsyだがnullishではない
const pet1 = animal1 ?? 'cat'
const pet2 = animal2 ?? 'dog'
console.log(pet1) // cat
console.log(pet2) // ''
&&
&& は左の値がTruthyな場合に、右側の値が評価される。
const adult = true
const drink = adult && 'alcohol'
console.log(drink) // alcohol
||=, ??=, &&=
Logical assignment operatorを使うことで変数の値を評価しつつ、結果によってそのまま値を代入することができる
let myPet = null
myPet ??= 'cat'
console.log(myPet) // 'cat'
let fluTestResult = 0
fluTestResult ||= 'negative'
console.log(fluTestResult) // 'negative'
let homework = 'acceptable'
homework &&= 'mathematics'
console.log(homework) // mathematics
String.prototype.replaceAll()
replaceAll() を使うと引数にマッチした文字列をすべて置換することができる。 replace() というメソッドも元々あるが、最初にマッチした文字列しか置換しないため、正規表現を使わないと複数の置換はできなかった。
const s = 'Rich mom poor mom'
const replaced = s.replace('mom', 'dad')
const replacedAll = s.replaceAll('mom', 'dad')
console.log(replaced) // Rich dad poor mom
console.log(replacedAll) // Rich dad poor dad
Promise.any()
[Javascript] forEach()はasync/awaitを待たない で使用したPromise.all() は全てのPromiseが終了するまで待つメソッドだったが、Promise.any() は複数のPromiseのうち、一つでも終了すればその時点で解決される。
const p1 = new Promise((resolve) => {
setTimeout(resolve, 500, 'Lion')
})
const p2 = new Promise((resolve) => {
setTimeout(resolve, 10, 'Cheetah')
})
const p3 = new Promise((resolve) => {
setTimeout(resolve, 2000, 'Munchkin')
})
Promise.any([p1, p2, p3]).then(res => {
console.log(res) // Cheetah
})
では全てのPromiseがrejectされた場合はどうかるか?その場合はAggregateErrorというエラーを吐くので、catchしてやるといい。
const p1 = new Promise((_, reject) => {
setTimeout(reject, 500)
})
const p2 = new Promise((_, reject) => {
setTimeout(reject, 10)
})
const p3 = new Promise((_, reject) => {
setTimeout(reject, 2000)
})
Promise.any([p1, p2, p3])
.then(res => res)
.catch(error => console.log(error.message)) // All promises were reject
WeakRef
WeakRefを使用することでJavascriptでも弱参照を作ることができ、参照する時はderef() を使用する。
const obj = { name: 'Alex' }
const weakRefObj = new WeakRef(obj)
console.log(weakRefObj.deref().name) // Alex
弱参照とは何か?というと、参照はされているものの参照先はガベージコレクションの対象になっている状態のこと。そして、ガベージコレルクションは、コンピューターが不要になったメモリ領域を解放することを意味する。
つまり簡単に言うと、参照はしてるけど使いたい時に参照先があるとは限らないよ、ということ。
使い所が難しそうだが、キャッシュのように有ったら有ったで助かるけど、無いなら無いでいい、というようなものを扱う時に重宝する。
ただし、ガベージコレクション周りの処理が複雑なため、可能であれば使用を避けるべきととされている。