2021-01 の TC39 meeting
まとめ
Agenda: https://github.com/tc39/agendas/blob/master/2021/01.md
速報: https://github.com/babel/proposals/issues/70
Note: https://github.com/tc39/notes/tree/master/meetings/2021-01
決まったこと
Web compatibility issues / Needs Consensus PRs
Runtime Semantics for MemberExpression do not conform to web reality (issue, PR)
仕様ではメンバ式で左辺に undefined と null を許容していないが、Web Reality としてはそれは許容されているので修正する提案。
code: (js)
'use strict';
undefined.foo = console.log('whoops');
承認された。
Stage 4 (ES2021)
Intl.DateTimeFormat.prototype.formatRange for Stage 4 (spec, PR, slides) | Felipe Balbontín
2つの Date を受け取って範囲の文字列を作る Intl メソッド。Stage 4 になった 🎉
Stage 3
Relative indexing method for stage 4 (Late addition, deprioritize) (slides) | Shu-yu Guo
indexable なクラスに対して at メソッドを追加し、引数に負数を入れた場合に後ろから値が取れる提案。
Chrome 89, Firefox 85, Safari Tech Preview 118 で実装されたが、とあるサイトで配列をハッシュテーブルとして利用しており、at プロパティの有無チェックをしているため互換性の問題が出てしまった。
Chrome, Safari Tech Preview についてはすでに unship されている。
RegExp Match Indices update (spec, slides) | Ron Buckton
RegExp#exec の返り値に indices プロパティを追加し、マッチした位置を取得できるようにする提案。
以前は問答無用で indices プロパティを追加する話だったが、パフォーマンスの問題が指摘されていた。そこで RegExp に新たなフラグとして d を指定したときのみ indices プロパティを追加する話になった。
JSON modules for stage 3 (slides) | Myles Borins, Daniel Ehrenberg, Sven Sauleau, Daniel Clark
ES Modules で JSON ファイルをオブジェクトとして読み込むことが出来るシンタックス。
code: (js)
import json from "./foo.json" assert { type: "json" };
レビュー途中だが、とりあえず条件付きで Stage 3 ということになった。
Class static Initialization Blocks for Stage 3 (tentatively) (spec, slides) | Ron Buckton
クラスの static 変数やメソッドを static initialization blocks シンタックスを使って定義することが出来るようにする提案。これによって static 変数、メソッドを定義するときに何らかの処理が必要な場合に即時函数などで括る必要がなくなる。
code: (js)
class C {
static x = ...;
static y;
static z;
static {
try {
const obj = doSomethingWith(this.x);
this.y = obj.y;
this.z = obj.z;
}
catch {
this.y = ...;
this.z = ...;
}
}
}
細かい仕様として new.target が undefined を返すことや、var のスコープが作られることが決まった。Stage 3 になった。
Stage 2
Array.isTemplateObject for stage 3 (slides) | Krzysztof Kotowicz
セキュリティのために Template Literal の Tag Functions として実行されたかどうかを判定することが出来る函数。この函数を追加することによってセキュリティを担保するというのが不十分という結論に至った。
Temporal updates (slides) | Ujjwal Sharma
細かな API の修正が進んでいるのと、Temporal.ZonedDateTime によって作られる文字列("1995-12-07T03:24:30.000003500+08:00[America/Los_Angeles]")を RFC3339 の拡張としてドラフトを書いているステータス。
3月の会議で Stage 3 にするとのこと。……やっとか。
ResizableArrayBuffer and GrowableSharedArrayBuffer updates (slides) | Shu-yu Guo
ArrayBuffer をリサイズできるクラスの提案。
Realms updates (slides tbd) | Leo Balter, Caridy Patiño
別のグローバルオブジェクト、組み込み函数としてコードを扱えるようにする提案。基本的にプログラム単位でグローバル変数の競合などを防いで管理しやすくする目的。
code: (ts)
declare class Realm {
constructor();
readonly globalThis: typeof globalThis;
import(specifier: string): Promise<Namespace>;
}
Ergonomic brand checks for private fields for stage 3 (issue) | Jordan Harband
Private fields に対してそのプロパティが存在するかどうかを判定することが出来るシンタックスの追加。
code: (js)
class Foo {
#bar = "bar";
test(obj) {
return #bar in obj;
}
}
JS Module Blocks for stage 2 (spec, slides) | Surma
Dynamic Imports や Web Workers, Worklets などで実行するコードは別ファイルとして用意しないといけないことになっているが、module blocks シンタックスを使うことでメインスレッドと同じファイルで容易に扱うことが出来る提案。
code: (js)
let moduleBlock = module {
export let y = 1;
};
let moduleExports = await import(moduleBlock);
assert(moduleExports.y === 1);
assert(await import(moduleBlock) === moduleExports); // cached in the module map
Stage 2 になった。
do expressions for stage 2 (slides, spec) | Kevin Gibbons
昔からほぼほぼ放置されていた Do Exporession の提案。変数の定義などのためにをブロックスコープ内でコードを実行することが出来る。
code: (js)
let x = do {
let tmp = f();
tmp * tmp + 1
};
return やループについての仕様の矛盾点が指摘された。
Intl Locale Info for stage 2 | Frank Yung-Fong Tang
Locale に対しての情報を取得する Intl メソッドを追加する提案。週の情報や、文字の方向などを取得できる。
code: (js)
const he = new Intl.Locale("he");
he.weekInfo; // { firstDay: 7, weekendStart: 5, weekendEnd: 6, minimalDays: 1 }
const ar = new Intl.Locale("ar");
ar.textInfo; // { direction: "rtl" }
const ja = new Intl.Locale("ja")
ja.defaults; // { calendar: "gregory", hourCycle: "h23", commonCalendars: "gregory", "japanes" }
もともと計測単位についても盛り込まれていたが、それを取り除いて Stage 2 になった。
Intl DisplayNames v2 for stage 2 | Frank Yung-Fong Tang
ブラウザが持っている翻訳文字列を取得することが出来る Intl メソッドの拡張。新たにカレンダーと計測単位の文字列を取得できる。Stage 2 になった。
Stage 1
Dynamic code brand checks for stage 2 (slides) | Krzysztof Kotowicz
eval や Function コンストラクタに与える引数に Trusted Types の TrustedScript を許容するために仕様を更新する提案。
async do expressions for stage 1 (slides, spec) | Kevin Gibbons
Do Expression に非同期を追加したもの。
code: (js)
let x = async do {
let res = fetch(x);
(await res).json()
};
x.then(console.log);
Stage 1 になった。
class brand check for stage 1 (slides) | HE Shi-Jun
オブジェクトがそのクラスのインスタンスかどうか判定するのに instanceof がよく使われる。これは Symbol.hasInstance を使ってカスタムすることが出来るが、記述するには困難になってしまっている。
例えば以下のようなコードを書いてしまった場合これは無限ループになる。
code: (js)
class C {
static Symbol.hasInstance(obj) {
return obj instanceof C;
}
}
よってインスタンスのプロトタイプについてチェックしたい場合は、自分でプロトタイプチェーンするコードを書く必要がある。
ここで新たにメタメソッドとして class.hasInstance を用意することで Symbol.hasInstance によって操作される前のデフォルトの instanceof の処理を扱うことが出来る。
code: (js)
class C {
static Symbol.hasInstance(o) {
return class.hasInstance(o);
}
}
これについては自分も考えたことがあるのでわかる。Stage 1 になった。
Extend TimeZoneName Option Proposal for stage 1 | Frank Yung-Fong Tang
Intl.DateTimeFormat のオプションの timezone に新たに "shortGMT", "longGMT", "shortWall" そして "longWall" を追加する提案。
Stage 1 になった。
eraDisplay option for Intl.DateTimeFormat for stage 1 (slides) | Shane F. Carr
Intl.DateTimeFormat のオプションとして era を扱うことが出来る "eraDisplay" を追加する提案。
Stage 1 になった。
Adopting Unicode behavior for set notation in regular expressions (slides) for stage 1 | Markus Scherer, Mathias Bynens
正規表現に対して差や交差のオペレーターを追加する提案。
code: (js)
// Ascii コードを除いた数値に一致する
/[\p{Decimal_Number}--0-9]/
// クメール語の Letter, Mark そして Number に一致する
/[\p{Script=Khmer}&&\p{Letter}\p{Mark}\p{Number}]/
Stage 1 になった。
Revisiting RegExp.escape | Jordan Harband
文字列から RegExp を作るときのためのエスケープ用メソッドの追加。
code: (js)
RegExp.escape("Buy it. use it. break it. fix it.") // "Buy it\. use it\. break it\. fix it\."
Stage 1 になった。
defer module import eval for stage 1 (slides) | Yulia Startsev
新たに ES Modules のロードツリーに lazyInit フラグを付け、それから読み込んだモジュールは最初に実行されたタイミングで評価される提案。
code: (js)
import aModule from "a-module" with { lazyInit: true };
function reralyUsedA {
// 略
aModule(); // この函数の評価は初めて使ったときに行われる
}
Dynamic Imports のように非同期として扱うのではなく、ファイル自体は予め読み込むことが出来、モジュールから読み込んだものも同期的に扱われる。
……パフォーマンス目的とはいえ、依存の管理が難しい感じがするな……。Stage 1 になった。
Intl LocaleMatcher for Stage 1 | Long Ho
Accept-Language HTTP ヘッダーのように要求された言語と、サイトが用意している言語のリストからマッチするものを選択してくれる Intl メソッドの追加。マッチの仕方のオプションとして "lookup" と "best fit" が用意されている。
code: (js)
Intl.LocaleMatcher.match("fr-XX", "en", "fr", "en", "en"); // 'fr'
index from end syntax for stage 1 (slides) | HE Shi-Jun
配列の後ろから値を取るシンタックスとして arr[^1] を追加する提案。他の提案であるスライス構文にマージして進めていくらしい。
Array find from last for stage 1 (slides) | Wenlu Wang
Array のミッシングピースとして後ろから find, findIndex することが出来る findLast, findLastIndex を追加する提案。
Stage 1 になった。
その他
Brand checking (discussion, slides) | Daniel Ehrenberg
Brand checking についての議論。将来的に仕様の形にまとめて Stage 1 にするつもりらしい。
The nature of protocols in JavaScript (issue, slides) (late addition) | Daniel Ehrenberg
Temporal のカスタムカレンダーや TimeZone をどう定義するかの議論。クラス? Symbol メソッド?
Spec complexity and planning for future implementations (slides, discussion) | Shane F. Carr, Zibi Braniecki
Intl を定義する ECMA-402 についての提案のコストを減らす議論。
総括
Temporal が Stage 3 にするする詐欺みたいな状況が長いこと続いていたがようやく Stage 3 になりそうでよかった。
また新しい提案として defer module import eval が気になった。モジュール周りはフロントエンドだと webpack や rollup などのバンドラーで対応する世界観になっているが、これはエミュレート出来ないけどどうするんだろうか……?
また正規表現に差や交差が提案されているのが面白い。
#ECMAScript