これは何
ECMAScript proposal updates @ 2020-07 | ECMAScript Dailyの簡単な要約です。次の JavaScript バージョンに加わる可能性のある新文法、新メソッド、新クラスがまとめられています。
正確・詳細な内容を知りたい方はリンク先をあたってください。そこまでするほどではないけどざっくり知りたい、という方向けです。
New Proposals
Proposal | Stage |
---|---|
Import Conditions | 2 |
WeakRefs cleanupSome | 2 |
JSON Modules - Note | 2 |
await operations | 1 |
Array.prototype.unique() | 1 |
ResizableArrayBuffer and GrowableSharedArrayBuffer | 1 |
Updated Proposals
Proposal | From | To |
---|---|---|
Promise.any | 3 | 4 |
WeakRefs | 3 | 4 |
Logical Assignment Operators | 3 | 4 |
Numeric separators | 3 | 4 |
.item() | 1 | 2 |
Record & Tuple | 1 | 2 |
JSON.parse source text access | 1 | 2 |
New Proposals
Import Conditions
JSON modules の import にアサーションが書けるようになります。
importjsonfrom"./foo.json"assert{type:"json"};
foo.json
が実際は JSON ではなかったときに、意図しないスクリプトを実行してしまうセキュリティ問題を防ぐためのようです。ファイルタイプを表すため慣例的に拡張子が使われているものの、本来 Web は拡張子という概念のない世界だから MIME Type とのミスマッチを明示的にすべき、らしいです。
アプリコードを書くときには煩わしいので、Babel や TypeScript による自動付与、VS Code による補完がどうなるか気になります。
WeakRefs cleanupSome
WeakRefs がわかっていないのでわからない
ガベージコレクションの話なので、よほど性能チューニングしたいときにしか使わなそう。
JSON Modules - Note
Import のアサーションと JSON modules の話は分けるべきでは?という議論。結論までちゃんと読んでないです。
await operations
Promise.all()
などが書きやすくなります。
// beforeawaitPromise.all(users.map(asyncx=>fetchProfile(x.id)));// afterawait.allusers.map(asyncx=>fetchProfile(x.id));
all
のほか race
, allSettled
, any
も。
Array.prototype.unique()
配列の重複を除くメソッドが使えるようになります。
constdata=[{id:1,uid:10000},{id:2,uid:10000},{id:3,uid:10001},];data.unique("uid");// [// { id: 2, uid: 10000 },// { id: 3, uid: 10001 }// ]data.unique(({id,uid})=>`${id}-${uid}`);// [// { id: 1, uid: 10000 },// { id: 2, uid: 10000 },// { id: 3, uid: 10001 }// ]
現時点でも [...new Set(array)]
によって配列の重複は除けますが、プリミティブ型でない値には使えません。その点を補います。
一方で、Record & Tuple によってオブジェクト的な値の同値性チェックが簡単になれば、プリミティブ型でない値にも使えるというメリットは薄まりそうです。メソッド名がわかりやすいので追加されること自体はよいことです。
ResizableArrayBuffer and GrowableSharedArrayBuffer
ArrayBuffer の派生クラスが増えます。
letrab=newResizableArrayBuffer(1024,1024**2);rab.resize(1024*2);
既存の ArrayBuffer は、領域を拡大するにはバッファーコピーが必要で非効率的だし、32-bit システムではアドレス空間のフラグメント化が生じるから、サイズ可変なこれらが欲しいとのこと。
あまり ArrayBuffer を使わないのでわかりませんが、動画のような巨大なバイナリ処理が効率化できるということでしょうか。
Updated Proposals
Promise.any
複数の promise のうちの一つが解決するまで待つ promise を作れます。
try{constfirst=awaitPromise.any(promises);// Any of the promises was fulfilled.}catch(error){// All of the promises were rejected.}
Promise.race([a, b, c])
は a
, b
, c
のどれか一つが 解決 or 拒否(失敗)すると解決 or 拒否します。Promise.any([a, b, c])
は a
, c
が拒否しても b
が 解決するまで待って、b
が解決したら解決、全部拒否したら拒否になります。
3 社の広告(接続先すべて別)のうちどれか一つを表示できればよい、といったケースで役に立ちそう?
WeakRefs
わからない
ガベージコレクション (GC) の話なので、よほど性能チューニングしたいときにしか使わなそう。iOS アプリなどと違って Web はページ単位のライフサイクルで、GC タイミングが多いはず(感覚です)。とはいえ Web の高機能化に伴って、明示的なメモリー管理も必要になるかもしれません。
Logical Assignment Operators
論理演算子も代入書式が使えるようになります。
opts.baz??="qux";// eqopts.baz??(opts.baz="qux");
i = i + 1
を i += 1
と書くようなものです。デフォルトオプションを設定するのに役立ちそう。||=
, &&=
, ??=
の 3 種類あります。
TypeScript 4.0 Beta ですでに導入されているようです (https://devblogs.microsoft.com/typescript/announcing-typescript-4-0-beta/)
Numeric separators
数値の桁をアンダースコア _
で区切れるようになります。
101_475_938.38===101475938.38;
すでにこう書けます(Chrome 84 や Node 13)が、仕様として定まっていないところがあったということでしょうか。ちゃんと読んでいないです。
.item()
N 番目の要素を取得するとき、負の値を指定できるようになります。
["a","b","c"].item(-1)==="c";
Array, String, TypedArray にメソッドが追加されます。[]
を使わないのは、それが配列インデックスだけでなくオブジェクトのプロパティを指定するときにも使われるためです。arr[-1]
という書き方は現状可能ですが、arr["-1"]
と書いたことになってしまいます。それらの区別をつけるため、明示的にメソッドを追加するようです。
Record & Tuple
イミュータブルな構造体として Record と Tuple が使えるようになります。
// Recordconstdoc=#{id:123,title:"foo",};doc.title==="foo";// Tupleconstm=#["x","y","z"];m[1]==="y";
Record はオブジェクトのような構造体、Tuple は配列のような構造体です。TypeScript はすでに as const
キーワードによってイミュータブルな構造体を表せますが、JS としても同様のことが可能になります。
一方 TypeScript でも実現できていない点として、同値性の評価があります。イミュータブルなので、中の構成が一緒なら同値であると評価するようです。
// non-Recordassert({x:1,y:2}!=={x:1,y:2});// Recordassert(#{x:1,y:2}===#{x:1,y:2});
プリミティブ型のようにイミュータブルかつ比較も簡単な値に、オブジェクトと同じ情報量を持たせられるのは強力です。
JSON.parse source text access
JSON.parse
のパーサーロジックを拡張できるようになります。
ちゃんと読んでいないです。