ECMAScriptの最新動向 2021年12月版
Published on
TC39 の 87 回目のミーティングが 12月14日 ~ 12月15日に開催されました。このミーティングで議題に上がった提案とそのステージの移動について紹介します。
For Stage 4
For Stage 4 の提案はありませんでした
For Stage 3
Array Grouping
Stage 3 になりました
Array Grouping は Array.prototype.groupBy
と Array.prototype.groupByToMap
を追加するプロポーザルです。
2021 年 10 月のミーティングで Stage 2 になったばかりですが、今回のミーティングで Stage 3 になりました。
また、今回から Array.prototype.groupByToMap
が追加されています。
これは groupBy
の結果が Map
になったものです。
const array = [1, 2, 3, 4, 5];
const odd = { odd: true };
const even = { even: true };
const map = array.groupByToMap((num, index, array) => {
return num % 2 === 0 ? even: odd;
});
console.log(map); // Map { {odd: true}: [1, 3, 5], {even: true}: [2, 4] }
For Stage 2
Array.fromAsync
Stage 2 になりました
Array.fromAsync
は非同期イテラブルから配列を生成するためのスタティックメソッドを追加するプロポーザルです。
JavaScript では Array.from
を使ってイテラブルから配列を生成できます。しかし、非同期イテラブルから配列を生成することはできません。
このプロポーザルによって追加される Array.fromAsync
メソッドを使うと次のようにして非同期イテラブルから配列を生成できます。
async function * asyncGen (n) {
for (let i = 0; i < n; i++)
yield i * 2;
}
const arr = await Array.fromAsync(asyncGen(4));
RegExp \R
escape
Stage 2 になりませんでした
RegExp \R
escape は以前 RegExp Language Features として提案されていた正規表現の機能群の1つで、正規表現内で line terminator とシンプルにマッチングさせるために新しく \R
を導入する提案です。
この機能は u
もしくは v
フラグが有効になっているときのみ有効になります。そして、大まかには次のパターンと等価です。
(?>\r\n?|[\x0A-\x0C\x85\u{2028}\u{2029}])
この正規表現の機能は Perl をはじめとする多くの正規表現エンジンに実装されていて、TC39 においてもそのユースケースは認められているようです。
しかし、RegExp Set Notation Proposal の sequece properties によって同等の機能が実現できる可能性があるためその方向で調査しなおすべきだという結論になり Stage 2 には到達しませんでした。
RegExp Modifiers
Stage 2 になりました
RegExp Modifiers は \R
escape と同じようにもともと RegExp Language Features の機能の1つでした。
この提案は正規表現パターン内でのフラグの変更を可能にします。
例を示します。
次の例中の正規表現パターン全体には i
フラグが適用されてます。しかし2つめの [a-z]
は ?-i:
という RegExp Modifiers の構文を使って i
フラグを無効にしてます。このとき一文字目では大文字小文字が無視されるものの、二文字目では大文字小文字が無視されません。
したがってこのパターンは "ab"
や "Ab"
にはマッチし "aB"
にはマッチしません。
const re1 = /^[a-z](?-i:[a-z])$/i;
re1.test("ab"); // true
re1.test("Ab"); // true
re1.test("aB"); // false
RegExp Buffer Boundaries
Stage 2 になりました
RegExp Buffer Boundaries も RegExp Language Features の機能の1つでした。
この提案は、それぞれ入力の最初と最後にマッチする \A
と \z
を導入します。m
フラグの影響を受けないことを除けば ^
と $
に似ています。
^
と $
はそれぞれ最初と最後にマッチしますが、m
フラグが有効になっているときは行頭と行末にマッチします。しかし RegExp Buffer Boundaries が導入する \A
と \z
は、たとえ m
フラグが有効であっても入力の最初と最後にマッチします。
例を示します。
const re = /\Afoo|^bar/um;
このパターンでは foo
に \A
がついています。したがって入力の最初が foo
の文字列にマッチします。
re.test("foo"); // true
re.test("foo\n"); // true
しかし入力の最初ではなく行頭が foo
の文字列にはマッチしません。
re.test("\nfoo"); // false
bar
には ^
がついています。パターン全体で m
フラグが有効になっているので、入力の先頭と行頭が bar
の文字列にマッチします。
re.test("bar"); // true
re.test("bar\n"); // true
re.test("\nbar"); // true
For Stage 1
Updates
ステージの移動はないものの、アップデートがあった提案です。
Temporal
いくつかの仕様上の軽微な修正がありました。修正箇所について説明したスライドが公開されています。
Decimal
Decimal は現在 Stage 1 ですが、2022 年に Stage 2 に到達することを目指しているそうです。進捗を共有するためのスライドが公開されています。
Destructuring Private Fields
Destructuring Private Fields が提案された当初は小さな修正で十分だと考えられていました。しかし真剣に検討してみるといくつかの仕様上の難しい問題が明らかになったそうです。そこで再度レビュワーを募りレビューをやり直すことが決定しました。
Shadow Realms
いくつかの仕様上の重要な変更があったようです。詳しくはスライドに記載されています。
Records and Tuples
Record と Tuple の中で通常のオブジェクトを扱う方法について議論されました。その方法とその懸念についての Decision Tree がスライドとして公開されています。
Normative Changes
import.meta[Symbol.toStringTag]
の追加
合意は得られませんでした
Symbol.toStringTag
という Well-known Symbol があります。
この Symbol は Object.prototype.toString()
によって表示される文字列の決定に使われます。
具体的な例を示します。
オブジェクト foo
の [Symbol.toStringTag]
に "I'm foo"
という文字列をセットしておくと、foo.toString()
は [object I'm foo]
になります。
const foo = {
[Symbol.toStringTag]: "I'm foo"
};
console.log(foo.toString()); // "[object I'm foo]"
今回のミーティングでは import.meta
の [Symbol.toStringTag]
に "ImportMeta"
という文字列を設定するという修正について議論されました。
この挙動についての Issue は import.meta
の策定時にも存在しましたが、そのときすでに import.meta
が Stage 4 を達成していたことからクローズされました。
そして今回のミーティングでもこの仕様の修正についての合意は得られませんでした。この修正のための Pull Request が作成された時点で以下のような懸念が公開されていました。
import.meta
は、ECMAScript の範囲ではHostGetImportMetaProperties
というホスト定義の abstract operation によって中身が決定されるオブジェクトであるということしか決まっておらず、ホストにとって必要であればホスト側でimport.meta
のSymbol.toStringTag
を定義できる。- 仕様内で作成される他のオブジェクトとは異なり、
import.meta
はホストのデータによって生成されるものであり、ECMAScript の範囲でプロパティを生成することを考慮したものではない。
参考リンク
- TC39
- Agenda for the 87th meeting of Ecma TC39
- Normative: Add import.meta[Symbol.toStringTag]
- Proposal Array Grouping
- Proposal Shadow Realms
- Proposal
Array.fromAsync
- Proposal RegExp Language Features
- Proposal RegExp
\R
escape - Proposal RegExp Set Notation
- Proposal RegExp Buffer Boundaries
- Proposal RegExp Modifiers
- Proposal Temporal
- Proposal Shadow Realms
- Proposal Records and Tuples
- Proposal Destructuring Private Fields
- Babel
- ECMA262
記事に関する報告などはこちらから