Upgrade to Pro — share decks privately, control downloads, hide ads and more …

tc39_study_2

1ff811939fd0923df8321ec6d8bf9d4b?s=47 Jxck
July 16, 2021

 tc39_study_2

#tc39_study のスライドです。

動画はこちら
TODO

元 Google Slide はこちら
https://docs.google.com/presentation/d/17znKhpHu__5SBcT0BNIaYHegy4mMs5MWzj59r-qzmeE

1ff811939fd0923df8321ec6d8bf9d4b?s=128

Jxck

July 16, 2021
Tweet

Transcript

  1. #tc39_study https://web-study.connpass.com/event/213676/

  2. 進め方 • CFP が通ったらこのスライドに編集権限を付与
 • 1 テーマ 1 slide のみ作成


    ◦ 右上の順番と時間以外は何をどう編集しても OK
 ◦ マスタスライドはいじいらない
 • 当日は主催がこのスライドを画面共有
 • 自分のターンだけミュートを解除し時間内に発表
 ◦ 30s: クリック音 (なくした)
 ◦ 3s 前: カウントダウン + ホーン
 • 時間になったら強制ミュート、すぐ次の人

  3. Pattern Matching (stage 1) - @jxck match (res) { if

    (isEmpty(res)) { handleEmpty() } when ({ status: 200, body, ...rest }) { handleBody(body, rest) } when ({ status: 301|302|303|307|308 }) { redirect(res) } when ^ClientError { clientError(req) } else { handleError() } } No1: 90s class ClientError { static [Symbol.matcher](status) { if (400 <= status && status <= 499) { return { matched: true } } } } matching clause or combinator match expression record / tuple などと組み 合わせるとさらに強力にな りそう。
  4. proposal-do-expression(@sadnessOjisan) • 何をするか: (中に文を書ける)do ブロックから値を返す↩ • 嬉しいこと: 式指向プログラミングが実現しやすくなる 👉 これまでは即時関数で頑張っていた

    👉 function(){if(){return}else{return}}() • 具体的なユースケース🔧 ◦ 局所変数: ある値を作るための一時変数が定義しやすい ◦ if式: 条件節やネストが複雑な 3項演算子は見にくい(と主張する人もいる) • 特にTS + Reactとの相性の良さに期待している 😘 ◦ 再レンダリングを気にせずに分岐を書ける(かもしれない) ▪ これまでは分岐ロジックを return の外に書くと、コンポーネントの粒度に よっては再レンダリングの範囲が大きくなる ◦ if や switch での分岐漏れを JSX 内から assertNever と呼ばれるテクニックで防 げる(かもしれない) ▪ これまでは 3項演算子を利用していたが、 3項演算子では assertNever できない No2: 90s babel や babel-preset-react ですでにサポートされている.実 装例: https://github.com/sadnessOjisan/do-playground const f = () => 3; let x = do { let tmp = f(); tmp * tmp + 1; }; const Component = (props) => ( <div className="myComponent"> {do { if (props.color === "blue") { <div style={{ color: "blue" }}>blue </div>; } else if (props.color === "red") { <div style={{ color: "red" }}>red </div>; } else if (props.color === "blue") { <div style={{ color: "blue" }}>blue </div>; } else { // assertNever とかができる! } }} </div> );
  5. Records & Tuples (Stage 2) • https://github.com/tc39/proposal-record-tuple • 再帰的イミュータブルな Object,

    Array欲しくない? • こう書きたい ◦ #{ x: 1, y: 2} // こっちが Record ◦ #[1, 2, 3, 4] // こっちが Tuple • 何ができる ◦ Record, TupleはプリミティブかRecord, Tupleしか含められない (String, Number, Boolean, undefined, null, Symbol, BigInt) ◦ Recordはドットアクセス、Tupleはインデックスアクセスできる ◦ 内容で比較できる ▪ #{ x: 1 } === #{ x: 1 } // true ▪ #[0, 1, 2] === #[0, 1, 2] // true ◦ Array.from()使える、Object.keys()も使えるようにしたい ◦ Tuple.from()、Record.fromEntries()を作る案もある No3: 90s @okunokentaro
  6. Observable - Stage 1 • 「川の上流からモノを流す => 下流のどこかでモノを受け取り、処理する」が簡便に 書ける ◦

    上流 = Observable, モノ = 任意の値, 流す = next(), 下流のどこか = subscribe() No4: 90s // 1,2,3の値を流したのち、 1000ミリ秒後に4を流して完了する Observable const observable = new Observable(subscriber => { subscriber.next(1); subscriber.next(2); subscriber.next(3); setTimeout(() => { subscriber.next(4); subscriber.complete(); }, 1000); }); console.log('==== just before subscribe ===='); observable.subscribe({ next(x) { console.log(`got value ${x}`); }, error(err) { console.error(`something wrong occurred: ${err}`); }, complete() { console.log('done!!!'); } }); console.log('==== just after subscribe ===='); ==== just before subscribe ==== got value 1 got value 2 got value 3 ==== just after subscribe ==== got value 4 done!!!
  7. const RGBOps = Operators( { "+"(a, b) { // エラーハンドリングは省略している雑な実装

    return { r: a.r + b.r, g: a.g + b.g, b: a.b + b.b, }; }, }, { right: Number, "*"(a, b) { return { r: a.r * b, g: a.g * b, b: a.b * b }; }, } ); class RGB extends RGBOps { r; g; b; constructor(hex) { this.r = parseInt(hex.slice(1, 3), 16); this.g = parseInt(hex.slice(3, 5), 16); this.b = parseInt(hex.slice(5, 7), 16); } } new RGB("#A1B2C3") + new RGB("#1A2B3C"); // Error。 with operators from RGB; new RGB("#A1B2C3") + new RGB("#1A2B3C"); // new RGB('#BBDDFF') No5: 90s Operator overloading (Stage 1) @arayaryoma Operator setの定義 “+”: RGBの各要素を加算する factory関数に定義を渡すと classが返ってくる “*” の右がNumber型だった場合の定義 RGBの各要素をN倍する RGB class に対して定義したOperator setを 有効にする Operators()から返ってきたclassを継承する with operators from RGB で利用を宣言 @use: operators も検討されているっぽい Initial commit: 2018/12/19 Latest commit: 2021/1/5 Champion: @littledan https://github.com/tc39/proposal-operator-ov erloading use cases • 複素数 • ベクトル・行列 • CSSの単位(emなど)
  8. Decorators - stage 2 • 関数・クラスを置き換えたり、メタデータを付 加したりできる機能 ◦ 例えば、関数の前後にログ出力を挿入したり ◦

    関数の前後でローディングを回してみたり ◦ 関数をイベントハンドラーにしたり ◦ クラスのメタデータをベースに DI してみたり etc • 強力な機能ゆえに問題が多く、過去3度白紙 に戻っている。 • 現在は4つ目のプロポーザル (simplified decorators) が策定中。過去のプロポーザル に比べて、runtime の perf penalty が少な い、traspile が簡単な事などが特徴 • Babel の実装が固まり次第 Stage 3 にアプ ライされる予定 (来年ぐらい?) No6: 90s Champion Chris Garrett
  9. Deferring Module Evaluation (@kaa_a_zu ) • ESModules によって モジュールは即座に実行されるようになった •

    1.読み込み 2.解析 3.評価 を即座に行うことのパフォーマンスは悪い • コストの問題を解決するため `import()` が使われているが、これは中のコード 全てを非同期 に実行してしまう ◦ 1)リファクタリングのコストが高くなる ◦ 2)読み込むモジュールの競合が発生する可能性がある • 3つの延期タイミング候補 ①Before Load ②Before Parse ③Before Evaluate ◦ Before Load 遅延は `import()` が行っている ◦ Before Parse 遅延は モジュール・グラフが存在しなくなるのでやめたい ◦ Before Eval 遅延は `import()` と組み合わせることで 起動時のI/Oコスト, 初期化コストを削減できる No7: 90s #Stage1 #パフォーマンス #モジュール評価遅延 /* import attribute方式 (stage3 import-assertion の将来) */ import {x} from "y" with { lazyInit: true } /* カスタムキーワード方式 */ lazy import {x} from "y";
  10. Module Fragments (@__sosukesuzuki) • Stage 1 • モジュールをインラインで記述するための文を導入する • プログラマは複数のファイルにそれぞれモジュールを書く

    • Native ESM として実行するとモジュールごとにfetchするのでパフォーマンス上の 懸念がある • 現代ではバンドルするのが主流だがバンドラの実装コストが高くモジュール構造が ランタイムまで残らず最適化に使うことができない • 1ファイルに複数のモジュールをバンドラから出力できればそれらの問題を解消で きる • module “#foo” { export const foo = “foo”; } みたいな構文 ◦ (少なくとも Stage 1 になったタイミングでは ) No8: 60s
  11. 🚨 proposal-error-cause @_keiya01 • Stage 3 • これまでは Error コンストラクタを拡張す

    る必要があった • Developer Tool などのツールでエラー の連鎖を扱い難い • この仕様により DevTool などのツール で Error の連鎖が見やすくなる No9: 60s https://github.com/tc39/proposal-error-cause https://twitter.com/FirefoxDevTools/status/1414965543593988104
  12. Import Assertions (@takanorip) • インポートするモジュールについてキータイプを明記、インポート時に正しいタイプのファイル がインポートされているか検証する仕組み • ウェブ上ではファイル拡張子と HTTP Content

    Typeヘッダーの間には、広くミスマッチが存在 するため、サーバーが予期せず異なる MIMEタイプを提供し予期せずコードが実行されてしま うことを防ぐことが目的 • 現在はJSON Modulesだけが提案されてるが、 HTML ModulesやCSS Modulesも議論中 No10: 60s
  13. standard libs can be loaded using import syntax. - import

    common way - import() dynamic async - importNow() sync for script Built In Modules aka JavaScript Standard Library (@yosuke_furukawa) No11: 60s Motivation Solution Import Semantics Contents No More !! Global property !!! - window - global Run Anywhere - Browser/Node/etc Namespace: `js:` reserved. - IANA register Module Freeze: - Object unextendable - enforce Object.freeze 本日の和気あいあいスレ https://github.com/tc39/proposal- built-in-modules/issues/16 - URL - Array / Set / etc - 個人的に欲しい: LinkedList, BinaryHeap, collection
  14. ユーザーによる 非同期処理の制御 が可能な protocol を定義 Cancellation API No12: 60s @progfay

    Stage 1 AbortController Cancellation API WHATWG DOM Standard EventTarget を用いた実装 AbortSignal と 1 対 1 対応 (派生なし) 主要ブラウザ、 Node.js で利用可能 TC39 Stage 1 (Last update: July 2018) Callback を用いた実装 派生先にもキャンセルが伝播する 参考実装あり (npm install prex) AbortController.follow() の提案あり
  15. Collection {coerceKey, coerceValue} - Stage 2 • Map のキーと値、Set のキーに

    アクセスする際にそれらを 変換する手段を提供 • Map と Set のコンストラクタの 第 2 引数を追加 • URLSearchParams、Header、 DomStringMap等の既存 ユースケースの実現を容易に No13: 60s https://github.com/tc39/proposal-collection-normalization const map = new Map([], { coerceKey: String }); // stored using { [[Key]]: "1", [[Value]]: "one" } in map.[[MapData]] map.set(1, 'one'); // looks for corresponding { [[Key]]: "1" } in map.[[MapData]] map.has(1); // true // functions directly exposing the underlying entry list are unaffected [...map.entries()]; // [["1", "one"]] const set = new Set([], {coerceValue: JSON.stringify}); // stored using { [[Value]]: '{"path": "/foo"}' } in set.[[SetData]] set.add({path: '/foo'}); // looks for corresponding { [[Value]]: '{"path": "/foo"}' } in set.[[SetData]] set.has({path: '/foo')}; // functions directly exposing the underlying entry list are unaffected [...set]; // ['{"path": "/foo"}']
  16. • https://github.com/tc39/proposal-decimal • 0.1 * 0.2 === 0.020000000000000004 // true

    ◦ IEEE754 倍精度浮動小数点数がどうのこうの(割愛) • JavaScript環境下での金額計算といった 10進数計算の正確さが 従来より求められるようになった ◦ Numberのままの実装は税率計算などでミスが起こる ◦ ライブラリの導入をせざるを得ない • typeof 1m === "bigdecimal" // true ◦ BigIntのようにリテラルは数値mで表現(例:1m, 234.56m) ◦ decimalのdじゃないの? ▪ 16進数表現の文字にdが含まれるから避けたい • リテラルでない表記、 Number値からの変換はBigDecimal(num) ◦ プリミティブの扱い、 new不要 No14: 60s @okunokentaro Decimal (Stage 1)
  17. JSON modules (@takanorip) • import assertionsをベースにJSONモジュールをインポートできるようにする仕組み • もともとimport assertionsの一部だったが、2020年7月に分割された •

    TC39でJSONモジュールを定義することで ECMA262に準拠したすべてのホストで一貫した動 作が保証される • JSONモジュールにアサーションが必要かどうかはホスト( Node.jsなど)が決定する No15: 60s
  18. 🧳 proposal-js-module-blocks @_keiya01 • Stage 2 • WorkerやWorkletのモジュールを別ファ イルに切り出さなければならないのは不 便

    • モジュールをインラインで書くことができ る • Module Blocks を参照することはできな い • structured cloneable No16: 60s https://github.com/tc39/proposal-js-module-blocks
  19. proposal-pipeline-operator No17: 60s @maxmellon stage-1 概要 備考 : 現在 pipeline

    に2つの style の提案が存在 • F# style • Hack Style F#, Elixer など 様々な言語にあるものに似たオペレーターを JavaScript にも 左辺の評価値を右辺の関数に適用するアレ partial-application-proposal と組み合わせるとより最高 > アローファンクションなしに,部分適用できるので便利 何が嬉しいの? .pipe(), pipe(), pipeP(), flow(), compose() で消耗したくない Mix-in と 組み合わせるのもアリ 自分は F# style のほうが好み Babel の実装があるので試すのおすすめ
  20. Limited ArrayBuffer (@Tsubame_misa) Stage1 ArrayButterを読み込み専用にしたり,一部分だけ読み書き可能にしたい デザインゴール • ArrayBufferをfreezeする ◦ 読み取り専用になる

    ◦ TypedArray/DataViewも読み取り専用になる • 読み取り専用のTypedArray/DataViewから書き込みに変換できないようにする • 小さな選択範囲から大きな範囲を読み込み書き込みできないようにする • 実装者にあまり複雑さを与えないように 嬉しい • 最小限のpermission/infomationの原則をArrayBuffer上で動かせる • Embedded JS enginesでROMを読み取り専用のArrayBufferとして表せる No18: 60s https://github.com/tc39/proposal-limited-arraybuffer
  21. Accessible Object.prototype.hasOwnProperty - Stage 3 • Object.prototype.hasOwnProperty をシンプルに書けるような、.hasOwn() の追加 •

    hasOwnProperty は、Object が引数と同じ property を持っているかを返す ◦ 「hasOwnProperty」という名称は、保護されていないので上書きが可能 😢 No19: 60s // before const obj = {foo: 'hoge'}; if (Object.prototype.hasOwnProperty.call(obj, 'foo')) { console.log('has property foo'); }; // after const obj = {foo: 'hoge'}; if (Object.hasOwn(obj, 'foo')) { console.log('has property foo'); }; // hasOwnProperty を上書きする例 const foo = { hasOwnProperty: (p) => { return false; }, bar: 'Here be dragons' }; foo.hasOwnProperty('bar'); // => 常に false を返してしまう ({}).hasOwnProperty.call(foo, 'bar'); // => true Object.prototype.hasOwnProperty.call(foo, 'bar'); // => true
  22. Partial Application Syntax - Stage 2 • 関数の部分適用を導入 • ?

    プレースホルダによる構文 • 関数、アロー関数、テンプレート文字列 を対象 • パイプライン演算との併用可 function add(x, y) { return x + y; } // Function#bind const addOne = add.bind(null, 1); addOne(2); // 3 // arrow functions const addTen = x => add(x, 10); addTen(2); // 12 // arrow functions and pipeline const newScore = player.score |> _ => add(7, _) |> _ => clamp(0, 100, _); const addOne = add(1, ?); // apply from the left addOne(2); // 3 const addTen = add(?, 10); // apply from the right addTen(2); // 12 // with pipeline let newScore = player.score |> add(7, ?) |> clamp(0, 100, ?); No20: 60s https://github.com/tc39/proposal-partial-application
  23. Realms (@takanorip) Realmオブジェクト内でJSを仮想化、実行できる仕組み 例 • WebベースのIDE • testing/mocking • ウェブ用のプラグイン(例:スプレッドシート関数)

    • サーバーサイドレンダリング • in-browser transpilation No21: 60s
  24. Temporal - stage3 (@sititou70) • Dateの欠点を克服するdate / time API ◦

    現状のDateオブジェクトは1995年の「java.util.Date」の一部がもとになっている ◦ もとになったAPIは(Temporalの中の人,@maggiepint氏曰く)率直に言って ひどいらしい ▪ 実際,1997年のJava 1.1で非推奨になっている • UTCオフセット / タイムゾーンのフルサポート • 日時の明確な文字列表現 ◦ →日付を曖昧に解釈・計算してしまうことによるバグを軽減 • 他にも:イミュータブル,グレゴリオ暦以外のカレンダーのサポート • (私見)既存の日付ライブラリと比較して ◦ Temporalは,タイムゾーン / オフセットを書き手にしっかり意識して書かせる印象(健全) ◦ 既存の「あまりタイムゾーン等を意識していないコード」を移植するのは少し大変? No22: 60s
  25. Dynamic Import Host Adjustment (@shisama_) ❏ 概要 ❏ Trusted Typesと相互運用性を持つための

    Proposal ❏ Trusted Typesとは? ❏ DOM-based XSSを防ぐためのブラウザのセキュリティ機能 ❏ Sinkへ代入する時にSourceの文字列を安全な型へ変換することを強制する ❏ Trusted Typesの問題 ❏ import()のモジュール指定子は文字列しか受け取れない仕様のため安全な型を強制できない ❏ Dynamic ImportはTC39の持ち物なのでWebの都合だけでは仕様を変更は難しそう No23: 60s // import()にtoString関数を含むオブジェクトを渡す const m = import({ toString() { console.log('ホストは任意の処理が可能 '); return trustedModule; }, }); m.then(() => console.log('module resolved' )) ❏ このProposalでできること ❏ import()にtoString関数を含むオブジェクトを渡す ❏ toString内では、ホスト(ブラウザに限らない)は モジュール指定子の検査・調整など任意の処理 が行える Stage 2
  26. No24: 60s ➢ Promiseを返すAtomics.wait() ➢ 内部的には,waiterListにAgentを追加する処理 を,新しい関数であるdoWait()でラップ ➢ これまで同期的に待つ必要があった Atomics.wait()をpromise-baseに書ける.

    → Atomics.waitAsync() - @you_5805
  27. proposal-readonly-collections (@sadnessOjisan) No25: 30s https://github.com/tc39/agendas/blob/master/2019/ 10.readonly-collections-as-recorded.pdf ES3 everything mutable ES6

    all collections mutable class AbstractMap { // A FixedMap, not necessarily fresh, whose state is this map's current // state. snapshot() :FixedMap; // A fresh Map whose initial state is this map's current state. diverge() :Map; // A ReadOnlyMap, not necessarily fresh, whose state is a read only // view of this map's current state. readOnlyView() :ReadOnlyMap(); // query-only methods of Map ... } マスタの管理とかがしやすくなるよ! ReadOnlyMap, FixedMap 例としてMap
  28. Grouped Accessors and Auto-Accessors for ECMAScript(@kumastry) Grouped Accessors セッターとゲッターをグループ化したもの 何が嬉しい❓

    ❓ ❓ ❓ ❓                       ・読みやすくなる Auto-Accessors Group Accessorsを簡略化したもの フィールドのアクセス権も初期化可能 何が嬉しい❓ ❓ ❓ ❓ ❓ ・フィールドのイミュータブル設定が簡単 ・ゲッターとセッター使わなくてもアクセス可能 No26: 30s https://github.com/rbuckton/proposal-grouped-and-auto-accessors
  29. Set and Map .of and .from (@oliver_diary) No27: 30s `Array.of`

    や `Array.from` のような メソッドをSetとMapにも追加する提案 元々のモチベーションは右のような形であったが、 `Array(0)` や `Array(0,1)`などのoverloadによって引数 の意味が異なるのが懸念点としてあるので `of`, `from` を 追加するのが良いのでは?という形になった • 具体的にはCollectionCreateという抽象操作(abstract operation)を追加し、それぞれのメソッド内で 呼び出すことでiterationを可能にしている • WeakSetやWeakMapにofやfromを追加する提案も同時にされている Stage1
  30. Export Default From (@Shinyaigeek 🐵) • default export されているものをnamed exportし直すことができる

    No28: 30s • この書き方と同義, 新しいuse caseをカバーするものというよりはより自然な文法を 提供するもの https://github.com/tc39/proposal-export-default-from • [[ExportName]] は default ではなく name
  31. async do expressions (@yoshiko_pg) Stage 1 • Stage1のdo expressionsにasyncをつけることで、新しい非同期コンテキストを生成でき る提案

    • 通常のdo expressionsの中でawaitすると、doの外側のcontextがblockingされる • async do expressionsの中でawaitすると、doの外側のcontextはblockingされない No29: 30s
  32. WHATWG URL (@Tsubame_misa) Stage 0 • WHATGW の URL, URLSearchParamsを

    ECMAScriptの仕様に導入したい • Web以外でも動いて嬉しい No30: 30s https://github.com/jasnell/proposal-url
  33. No31: 30s Slice notation (Stage 1) @arayaryoma const array =

    ["a", "b", "c", "d"]; array.slice(1, 3); // => ['b', 'c'] array.slice(3); // => ['d'] array.slice(-2); // => ['c', 'd'] // array.slice(1, 3)と同等 array[1:3] // => ['b', 'c'] // array.slice(0, 3)と同等 array[:3]; // => ['a', 'b', 'c'] // array.slice(1)と同等 array[1:]; // => ['b', 'c', 'd'] // コピーが作られる。 array.slice()と同等 array[:]; // => ['a', 'b', 'c', 'd'] // array.slice(-2)と同等 array[-2:]; // => ['c', 'd'] // array.slice(0, -10) と同等 array[:-10]; // => [] Initial commit: 2018/5/2 Latest commit: 2020/7/12 Champion: @gsathya https://github.com/tc39/proposal-slice-notati on Array.prototype.slice 引数が1つのときの挙動が 分かりづらくない? 新しい記法の提案 対応表: • a[n:m] ⇔ a.slice(n, m) • a[n:] ⇔ a.slice(n) • a[:m] ⇔ a.slice(0, m) • a[:] ⇔ a.slice()
  34. Array Equality - Stage 1 • 配列の「要素の値」が等しいかを返す .equals() の追加 ◦

    単純な比較では、配列の参照元(アドレス)を比較してしまい、狙った挙動にならない 😢 No32: 30s [1, 2, 3].equals([1, 2, 3]); // => true [1, 2, undefined].equals([1, 2, 3]); // => false [1, [2, [3, 4]] ].equals([1, [2, [3, 4]] ]); // => true const a = [ {foo: 'bar'}, {foo: 'baz'} ]; const b = [ {foo: 'bar'} ]; a.equals(b); // => false
  35. • Stage1 • このproposalで追加されるArray.prototype.filterRejectはコールバック関数で実装 されたテストに不合格だったすべての要素からなる新しい配列を生成する • Array.prototype.filter()はコールバック関数で実装されたテストに合格したすべての 要素からなる新しい配列を生成する • 類似するメソッドとして、RubyにArray#reject、Underscoreに_.reject、Lodashに

    _.rejectや_.partitionがある No33: 30s proposal-array-filtering (Forest_Y)
  36. 現状での再現方法: [...arr].reverse().find() array-find-from-last No34: 30s @progfay Stage 2 Array.prototype.findLast(), Array.prototype.findLastIndex()

    を追加 • 不必要なパフォーマンスの低下を招く • index を取得したい場合には不便 不要なcopy 不要なmutation
  37. Array.prototype.uniqueBy() (@autummn_fish)
 • Stage1
 • 重複する要素を削除した新しい配列を返すメソッド 
 • 非プリミティブ型に対応した[...new Set(array)]を返す

    
 • 引数としてNumber,String,Symbolを指定可能 
 ◦ 引数をkeyとして重複要素の削除を行う
 • 関数を引数として渡せる
 ◦ 配列の各要素ごとに関数を呼び出し、関数の戻り値に基づいて重複要素を削除する 
 • 0と-0の区別はない
 • 空、もしはNullishな値の場合Nullishとして扱われる 
 • NaNは区別されない
 No35: 30s
  38. No36: 30s @okunokentaro • https://github.com/jasnell/proposal-deprecated • JSDoc @deprecated ◦ これをセマンティックにしたい

    • 2つのやり方が考えられる ◦ deprecated global ◦ 'deprecated' pragma • pragmaだと理由とか書けそうだよね ◦ 'deprecated; This is deprecated, use something else' Deprecated (stage 0)
  39. await.ops (@__sosukesuzuki) • Stage 1 • await Promise.(all/race/any/allSettled) promises という形はよく使われる

    • が、微妙に記述量が多くだるい ◦ await Promise.all(hoges.map((hoge) => someOperation(hoge))); • 短く簡単に書きたい • await.(all/race/any/allSettled) promises ◦ await.all hoges.map((hoge) => someOperation(hoge)); • カッコが減るとうれしい • 余談 ◦ https://github.com/sosukesuzuki/babel/pull/4 ◦ で Babel に実装をしている最中です No37: 60s
  40. モチベーション ➢ ある非同期関数の呼び出しで,実際に処理が行われる のが同期処理のみである場合,これをタスクキューでは なく即座にコールスタックに追加したい ➢ 下7行目でも可能だが直感的でない アプローチ ➢ Promise.try(f)でこれを達成

    No38: 30s → Promise.try() - @you_5805
  41. Deep Path Properties in Record Literals (@yoshiko_pg) • Stage2のRecords &

    TuplesのRecordを前提としたProposal • RecordにネストしたRecordのkeyを表現するときに . を使える • RecordにネストしたTupleのindexを表現するときに [] を使える • Objectへの追加は提案していない。 immutableであることを前提とした提案 • 存在しない箇所にアクセスしたら TypeError。 ?で無効化する提案がissueに出ている↓ • ↓既存のRecordを元に新しいRecordを作成するbefore/after No39: 30s before(現在) after
  42. Function.isCallable() / Function.isConstructor() - Stage 0 • Function.isCallable( argument )

    1. If IsCallable(argument) is false, return false. 2. If argument has a [[isClassConstructor]] internal slot with value true, return false. 3. Return true. • Function.isConstructor( argument ) 1. Return IsConstructor(argument). • IsCallable, IsConstructor: ECMAScript SpecificationのAbstract Operations No40: 30s https://github.com/caitp/TC39-Proposals/blob/HEAD/tc39-reflect-isconstructor-iscallable.md
  43. Class brand check (@kumastry) 一言で言うと instanceof のstaticメゾット版 他のクラスベースのOOPプログラミング言語と同様のコンセプトモデルを提供する class.hasInstance(o) ⇔

    o instanceof class classにはclass名,oにはインスタンスが入る 乙 \(・。・?)/ No41: 30s https://github.com/tc39/proposal-class-brand-check
  44. Generator function.sent Meta Property (@Shinyaigeek 🐵) • Generator関数の中で利用できるメタプロパティ No42: 30s

    • yieldを呼べるところでならどこででも参照できる • 直近で呼ばれたgenerator objectのnext関 数の引数を取得できる • Generator関数の構造上, 最初に呼ばれるnext関 数の引数にアクセスする方法がない問題に対応し ている https://github.com/tc39/proposal-function.sent
  45. Generator Arrow Functions (@oliver_diary) No43: 30s • generator構文をArrow functionsに追加する提案と `generator`

    キーワードを追加し `ASI hazard` を避ける提案の2つが上がっている。 • 現在はArrow functionsのどこにアスタリスクを付けるかに議論が集中しているが、 `() =*>` に軍配が上がりそうな感じではある。 generatorキーワードの提案 アスタリスク記法の候補 現状の有力候補 Stage1
  46. 🙈 proposal-private-fields-in-in @_keiya01 • Stage 4 • 指定した Private Field

    を持っているか どうかをチェックしたい • `try {} catch {}` を使えばできるが、 余計な例外もキャッチしてしまう • `in` キーワードを使って指定された Private Fieldを持っているかどうかを判 定できる No44: 30s https://github.com/tc39/proposal-private-fields-in-in
  47. • Stage1 • Array.prototypeもしくはTypedArray.prototypeに対して変更を行うメソッドを追加す るproposalになる • 類似する既存のメソッドでは対象となるArray(TypedArray)に対して破壊的に変更 されるのに対し、追加されるメソッドでは対象となるArray(TypedArray)に対し非破 壊的に変更を行う •

    対象メソッドはArray.prototype.fill(value, start, end)やArray.prototype.pop()など の全10種類 No45: 30s Change Array by copy (Forest_Y)
  48. Iterator Helpers (@shisama_) • IteratorとAsyncIteratorに.map()や.filter()などの 便利メソッドを生やすProposal • IteratorをArrayのように扱うためのライブラリはす でにある itertools,

    lodash, ix...etc • Rust、Python、C#ではIteratorで便利メソッドを使 うことができる • 現在提案されているのは... .map() .filter() .take() .drop() .asIndexedPairs() .flatMap() .reduce() .toArray() .forEach() .some() .every() .find() .from() No46: 30s function* naturals() { let i = 0; while (true) { yield i; i += 1; } } const result = naturals() .filter(value => { return value % 2 == 0; }); result.next(); // {value: 0, done: false}; result.next(); // {value: 2, done: false}; result.next(); // {value: 4, done: false}; Stage 2
  49. Array.prototype.at() (@autummn_fish)
 • Stage3 • 負の添字を指定した場合、配列末尾から N番目の要素を返すメソッド ◦ Pythonのように添字を扱えてうれしい ◦

    現状ではarr[arr.length-N]のように記述できるが冗長だし匿名の値の場合一時変数を用意しなければならない ◦ arr.slice(-N)[0]としても記述可能だが、新しい配列を作成してしまう No47: 30s
  50. Symbols as WeakMap keys (@nkowne63) • Stage 2 • Symbolを新たにWeakMapのkeyとして利用できるようにするProposal

    • 今まではWeakMapを使うために適当なオブジェクトを生成するなどの必要があっ たが、そんなことをしなくてもWeakMapが使えるようになる • そもそもWeakMapはGCをするためにkeyをuniqueにする必要があるのだが、 Symbolは基本的にuniqueということで提案されている。 • 実際は、Symbol.forといった(直接共有されていなくても)取得可能なSymbolがあ る(つまり、GCできないものがある)ため、どうするかは議論中とのこと。 No48: 30s
  51. New Set methods (@mignon8) No49: 30s methods 例:A.intersection(B) return values

    Set.prototype.intersection() A∩B (共通集合/積集合) AとB両方に入っている要素の集合を返す Set.prototype.union() A∪B (和集合) AとBの、片方または両方に入っている要素の集合を返す Set.prototype.difference() A\B (差集合) Aの中から、Bに属する要素を取り去った集合を返す Set.prototype.symmetricDifference() (A\B)∪(B\A) (対称差) AとBの、片方にだけ属する要素からなる集合を返す Set.prototype.isSubsetOf() A⊆B (部分集合)の真偽 Aが、Bの一部の要素だけからなる集合か否かの真偽値を返す Set.prototype.isSupersetOf() A⊇B (部分集合)の真偽 Bが、Aの一部の要素だけからなる集合か否かの真偽値を返す Set.prototype.isDisjointFrom() A∩B=Φ(空集合)の真偽 AとBの共通集合が、空集合か否かの真偽値を返す ・このproposalには含まれていないが、検討の価値ありとされているクラスメソッドもある  Set.union(...iterables)  Set.intersection(...iterables) ※引数はiterable https://github.com/tc39/proposal-set-methods
  52. 嬉嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉

    嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 No50: 30s #tc39_study / @TakumaNitori ECMAScript Module (ESM) CommonJS Module (CJS) ♥ 明確なスコープ ♥ 不要な as 改名を撲滅 ♥ 起動時のオーバーヘッド削減 ♥ impo エラーがブロック内完結 ♥ if / switch で読ませない選択肢 ♥ try catch できる 〜 嬉しいポイント 〜 ネ ス ト 出 来 な い 出 来 な い 出 来 な い 「 で き る 」 Stage: 0 / Nested impo declarations Stage: 0 / Nested impo declarations ECMAScript Proposal: Nested import declarations (https://github.com/benjamn/reify/blob/HEAD/PROPOSAL.md) 【公式】 ダーリンダンス/かいりきベア feat.初音ミク (https://www.youtube.com/watch?v=Rkrm5foi188&t=55s) スコープ 呼び出し箇所 import 名
  53. Math Extensions No51: 30s @progfay Stage 1 Math.clamp(x, lower, upper):

    xを[lower, upper]の区間で丸めた値を返す upper lower x1 x2 x3 ret1 ret2 ret3 Math.scale(x, inLow, inHigh, outLow, outHigh): xを[inLow, inHigh]から[outLow, outHigh]にマッピングした値を返す x ret in out Math.RAD_PER_DEG ⇄ Math.DEG_PER_RAD Math.radians(deg) ⇄ Math.degrees(rad)
  54. proposal-string-dedent (@sadnessOjisan) No52: 30s ♂ ♂ class MyClass { print()

    { console.log(`create table student( id int primary key name text )`) } } class MyClass { print() { console.log(` create table student( id int primary key name text ) `) } } class MyClass { print() { console.log(``` create table student( id int primary key, name text ) ```) } }
  55. Upsert (@Shinyaigeek 🐵) • Update + Insert No53: 30s •

    Mapに(key, value)を追加する際, 既にkeyが 登録されている時(update)とされていない時 (insert)の処理をかける • insert, updateは省略可能であり, 省略された 時は何もしない. https://github.com/tc39/proposal-upsert • しかしinsertが省略されていてかつkeyがMapに 登録されていないときはRuntimeErrorになる
  56. No54: 30s throw expression (Stage 2) @arayaryoma // throw statement

    function hello(name) { if (name === undefined) { throw new Error("arg: name must be passed"); } console.log(`Hello, ${name}`); } // throw expression function hello(name = throw new Error("arg: name must be passed")) { console.log(`Hello, ${name}`); } hello(); // Error 'arg: name must be passed' // throw statement const result = obj?.a?.b; if (result === undefined || result === null) { throw new Error("obj.a.b is undefined"); } // throw expression const result2 = obj?.a?.b ?? throw new Error("obj.a.b is undefined"); Initial commit: 2017/7/16 Latest commit: 2018/1/24 Champion: @rbuckton https://github.com/tc39/proposal-slice-notati on throw を式で書ける 関数のデフォルト値として定義したり ?. や ?? と組み合わせると便利 引数がなかったら throwする プロパティがなかったら throwする
  57. JavaScript standard library UUID (@oliver_diary) • 標準ライブラリとしてRFC 4122に基づいたUUIDを提供する提案 • npmのuuidモジュールがとても多く使われてる現状と、

    RFC 4122に触れたことのない開発者が 車輪 の再発明をした際に衝突のリスクがある観点から、標準化することで 「CSPRNG」と呼ばれる「暗号論的擬似乱数生成器」を強制することができるのがモチベーションとし てある。 No55: 30s 提案されているAPI (crypto interface に追加パターン) 他に考えられる選択肢 (メソッドをグローバルに公開パターン ) crypto名前空間に含めることでCSPRNGを使用してUUIDを生成するという 要件を強調している Stage1
  58. Seeded Pseudo-Random Numbers (@Tsubame_misa) stage 1 再現可能なランダム値を生成できるようにしたい • PRNGの作成:Math.seededRandoms() ◦

    乱数種の設定 ◦ 引数にseedプロパティを持ったオブジェクトを渡す • .random() で乱数生成を行う • .seed で複製ができる • サブPRNGの作成:randomSeed() No56: 30s https://github.com/tc39/proposal-seeded-random
  59. WeakRefs (@likr) • Stage 4 (2020年7月)、ES2021 • GCに回収されても良いような弱参照を実現 ◦ キャッシュ機構の実装

    ◦ destructor(WebAssembly向け) • WeakRef class • FinalizationRegistry class 変数、配列、 オブジェクト 弱参照 変数、配列、 オブジェクト オブジェクト オブジェクト GC対象外 弱参照 オブジェクト オブジェクト GC対象 No1: 90s DEMO
  60. sosukesuzuki import.meta - 数少ない Meta Property の1つ - 現在実行中のモジュールにホスト固有のメタデータを提供する -

    ECMAScript ではオブジェクトであることしか決まっていなくて、中身はホスト環境 に委ねられている - Web では import.meta.url が生えている - 実行されているモジュールの URL を表す - https://sosukesuzuki.dev/index.mjs では import.meta.url は https://sosukesuzuki.dev/index.mjs - Node.js でも import.meta.url のみ生えている - 実行されているモジュールのファイルの URL を返す(file スキームになる) - ESM では __filename や __dirname を使えないので、その代わりになる - “module” モジュールの createRequire の引数の import.meta.url を渡すと CJS Modules での require が手に入る - 移行や相互運用の際に便利 No2: 60s DEMO
  61. Promise.any() @okunokentaro 60s • ES2021で追加 • Promise.all()とかの仲間 Support すべて待つか rejectが含まれたら

    Promise.all() ES2015 待つ すべて待たずにrejectを返す Promise.race() ES2015 待たずに最初のresolve/rejectを返す そのrejectを返す Promise.allSettled() ES2020 待つ すべて待ってすべての結果を返す Promise.any() ES2021 待たずに最初のresolveを返す すべてがrejectのときAggregateError https://github.com/tc39/proposal-promise-any https://stackblitz.com/edit/rxjs-bhelsu No3: 60s DEMO
  62. import() ES2020 • ESMを動的にimport (dynamic import) • 引数にmoduleのpath渡す • 非同期関数で、結果を

    resolve するPromiseを返す • named exportはnameがkey • default exportは”default”が key @arayaryoma No4: 30s DEMO