この章では、ES2016~ES2022の新しい機能を逆時間順にリストアップしています。ES2015(ES6)以降を対象としています。ES2015は機能が多すぎるため、ここではリストアップしていません。
ES2022は、2022年6月に標準になる予定です。以下の提案はステージ4に達しており、この標準の一部になる予定です。
クラスの新しいメンバー
プライベートスロットチェック(「プライベートフィールドのエルゴノミックブランドチェック」):以下の式は、objがプライベートスロット#privateSlotを持っているかどうかをチェックします。
#privateSlot in objモジュールにおけるトップレベルのawait:モジュールのトップレベルでawaitを使用できるようになり、非同期関数やメソッドに入る必要がなくなりました。
error.cause:Errorとそのサブクラスでは、現在発生しているエラーの原因となったエラーを指定できるようになりました。
new Error('Something went wrong', {cause: otherError})インデックス可能な値のメソッド.at()を使用すると、指定されたインデックスの要素を読み取ることができます(ブラケット演算子[]に似ています)。ブラケット演算子とは異なり、負のインデックスもサポートします。
> ['a', 'b', 'c'].at(0)
'a'
> ['a', 'b', 'c'].at(-1)
'c'以下の「インデックス可能」な型は、メソッド.at()を持っています。
文字列配列Uint8Arrayなど正規表現のマッチインデックス:正規表現にフラグを追加すると、各グループキャプチャの開始インデックスと終了インデックスを記録するマッチオブジェクトが生成されます。
Object.hasOwn(obj, propKey)は、オブジェクトobjがキーpropKeyを持つ独自の属性を持っているかどうかをチェックする安全な方法を提供します。Object.prototype.hasOwnPropertyとは異なり、すべてのオブジェクトで動作します。
ES2022にはさらに機能が追加される可能性があります
そのような場合、本書はそれに合わせて更新されます。
ECMAScript 2021では、以下の機能が追加されました。
String.prototype.replaceAll()を使用すると、正規表現または文字列のすべてのマッチを置換できます(.replace()は文字列の最初の出現のみを置換します)。
> 'abbbaab'.replaceAll('b', 'x')
'axxxaax'Promise.any()とAggregateError:Promise.any()は、Promiseのイテラブルの最初のPromiseが解決されるとすぐに解決されるPromiseを返します。拒否のみがある場合、それらはAggregateErrorに入れられ、拒否値になります。
複数のPromiseの中で、最初に解決されたPromiseのみに関心がある場合に、Promise.any()を使用します。
a ||= b
a &&= b
a ??= b区切り文字としてのアンダースコア(_)
123_456.789_0126_000_000_000_000_000_000_000_000nWeakRefs:この機能は本書の範囲外です。詳細については、その提案を参照してください。
ECMAScript 2020では、以下の機能が追加されました。
新しいモジュール機能
import()による動的インポート:通常のimport文は静的です。モジュールのトップレベルでのみ使用でき、そのモジュール指定子は固定された文字列です。import()はそれを変更します。どこでも使用でき(条件文を含む)、その引数を計算できます。
import.metaには、現在のモジュールのメタデータが含まれています。その最初の広くサポートされているプロパティはimport.meta.urlで、現在のモジュールのファイルのURLを含む文字列が含まれています。
名前空間の再エクスポート:以下の式は、モジュール'mod'のすべてのエクスポートを名前空間オブジェクトnsにインポートし、そのオブジェクトをエクスポートします。
export * as ns from 'mod';プロパティアクセスとメソッド呼び出しのためのオプショナルチェイニング。オプショナルチェイニングの例を以下に示します。
value.?propこの式は、valueがundefinedまたはnullのいずれかの場合、undefinedになります。それ以外の場合は、value.propになります。この機能は、プロパティの一部が欠落している可能性のあるプロパティ読み取りの連鎖で特に役立ちます。
value ?? defaultValueこの式は、valueがundefinedまたはnullのいずれかの場合、defaultValueになり、それ以外の場合はvalueになります。この演算子を使用すると、何かが欠落している場合にデフォルト値を使用できます。
以前は、この場合に論理和演算子(||)が使用されていましたが、左辺が偽の場合にデフォルト値を返すため(常に正しいとは限らない)、欠点があります。
BigInt - 任意精度の整数:BigIntは新しいプリミティブ型です。任意の大きさの整数をサポートします(ストレージは必要に応じて大きくなります)。
String.prototype.matchAll():このメソッドは、フラグ/gが設定されていない場合にスローされ、指定された文字列のすべてのマッチオブジェクトを含むイテラブルを返します。
Promise.allSettled()は、Promiseのイテラブルを受け取ります。すべての入力Promiseが確定するとすぐに解決されるPromiseを返します。解決値は、入力Promiseごとに1つのオブジェクトを含む配列です。いずれか一方です。
{ status: 'fulfilled', value: «解決値» }{ status: 'rejected', reason: «拒否値» }globalThisは、ブラウザとNode.jsやDenoなどのサーバーサイドプラットフォームの両方で動作するグローバルオブジェクトにアクセスする方法を提供します。
for-inメカニズム:この機能は本書の範囲外です。詳細については、その提案を参照してください。
ECMAScript 2019では、以下の機能が追加されました。
配列メソッド.flatMap()は.map()のように動作しますが、単一値ではなく、0個以上の値の配列をコールバックが返すことができます。返された配列は連結され、.flatMap()の結果になります。使用例としては、以下があります。
配列メソッド.flat()は、ネストされた配列をフラットな配列に変換します。オプションで、どのネストの深さでフラット化を停止するかを指定できます。
Object.fromEntries()は、エントリのイテラブルからオブジェクトを作成します。各エントリは、プロパティキーとプロパティ値を持つ2要素の配列です。
文字列メソッド:.trimStart()と.trimEnd()は.trim()のように動作しますが、文字列の先頭または末尾の空白のみを削除します。
省略可能なcatchバインディング:使用しない場合は、catch句のパラメータを省略できるようになりました。
Symbol.prototype.descriptionは、シンボルの説明を読み取るためのゲッターです。以前は、説明は.toString()の結果に含まれていましたが、個別にアクセスできませんでした。
これらの新しいES2019機能は、本書の範囲外です。
JSON.stringify():2alityブログ投稿を参照してください。Function.prototype.toString()の改訂:2alityブログ投稿を参照してください。ECMAScript 2018では、以下の機能が追加されました。
非同期イテレーションは、同期イテレーションの非同期バージョンです。Promiseに基づいています。
awaitする必要があります。for-ofループを使用します。非同期イテラブルでは、for-await-ofループを使用します。オブジェクトリテラルへのスプレッド:オブジェクトリテラル内でスプレッド(...)を使用することにより、別のオブジェクトのプロパティを現在のオブジェクトにコピーできます。1つのユースケースは、オブジェクトobjのシャローコピーを作成することです。
const shallowCopy = {...obj};レストプロパティ(デストラクチャリング):値をオブジェクトデストラクチャリングする際に、レスト構文(...)を使用して、以前に言及されていないオブジェクト内のすべてのプロパティを取得できるようになりました。
const {a, ...remaining} = {a: 1, b: 2, c: 3};
assert.deepEqual(remaining, {b: 2, c: 3});Promise.prototype.finally()は、try-catch-finally文のfinally句に関連しています。Promiseメソッド.then()がtry句に関連し、.catch()がcatch句に関連しているのと同様です。
言い換えれば:.finally()のコールバックは、Promiseが解決されるか拒否されるかに関係なく実行されます。
新しい正規表現機能
RegExpの名前付きキャプチャグループ:番号でグループにアクセスすることに加えて、名前を付けて名前でアクセスできるようになりました。
const matchObj = '---756---'.match(/(?<digits>[0-9]+)/)
assert.equal(matchObj.groups.digits, '756');RegExpの後読みアサーションは、先読みアサーションを補完します。
(?<=X)は、現在の位置が'X'の前にある場合にマッチします。(?は、現在の位置が'(?の前にない場合にマッチします。正規表現のs(dotAll)フラグ。このフラグが有効な場合、ドットは行終端文字と一致します(デフォルトでは、一致しません)。
RegExpのUnicodeプロパティエスケープは、Unicodeコードポイントのセットをマッチングする際に、より強力な機能を提供します。たとえば、
> /^\p{Lowercase_Letter}+$/u.test('aüπ')
true
> /^\p{White_Space}+$/u.test('\n \t')
true
> /^\p{Script=Greek}+$/u.test('ΩΔΨ')
trueテンプレートリテラルの改訂により、文字列リテラルでは不正なタグ付きテンプレート内のバックスラッシュを含むテキストが許可されます。たとえば、
windowsPath`C:\uuu\xxx\111`
latex`\unicode`ECMAScript 2017では、以下の機能が追加されました。
非同期関数(async/await)を使用すると、同期的な構文を使用して非同期コードを記述できます。
Object.values()は、指定されたオブジェクトのすべての列挙可能な文字列キー付きプロパティの値を含む配列を返します。
Object.entries()は、指定されたオブジェクトのすべての列挙可能な文字列キー付きプロパティのキーと値のペアを含む配列を返します。各ペアは、2要素の配列としてエンコードされています。
文字列パディング:文字列メソッド.padStart()と.padEnd()は、レシーバが十分な長さになるまでパディングテキストを挿入します。
> '7'.padStart(3, '0')
'007'
> 'yes'.padEnd(6, '!')
'yes!!!'関数パラメータリストと呼び出しにおける末尾のカンマ:末尾のカンマは、ES3以降の配列リテラルとES5以降のオブジェクトリテラルで許可されていました。関数呼び出しとメソッド呼び出しでも許可されるようになりました。
以下の2つの機能は、本書の範囲外です。
Object.getOwnPropertyDescriptors()(“Deep JavaScript”を参照)ECMAScript 2016では、以下の機能が追加されました。
Array.prototype.includes() は、配列が指定された値を含むかどうかをチェックします。
> 4 ** 2
16ECMAScript の機能リストは、TC39 の完了済みの提案に関するページから取得しました。