Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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


Slide 3

Slide 3 text

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 などと組み 合わせるとさらに強力にな りそう。

Slide 4

Slide 4 text

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) => (
{do { if (props.color === "blue") {
blue
; } else if (props.color === "red") {
red
; } else if (props.color === "blue") {
blue
; } else { // assertNever とかができる! } }}
);

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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!!!

Slide 7

Slide 7 text

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など)

Slide 8

Slide 8 text

Decorators - stage 2 ● 関数・クラスを置き換えたり、メタデータを付 加したりできる機能 ○ 例えば、関数の前後にログ出力を挿入したり ○ 関数の前後でローディングを回してみたり ○ 関数をイベントハンドラーにしたり ○ クラスのメタデータをベースに DI してみたり etc ● 強力な機能ゆえに問題が多く、過去3度白紙 に戻っている。 ● 現在は4つ目のプロポーザル (simplified decorators) が策定中。過去のプロポーザル に比べて、runtime の perf penalty が少な い、traspile が簡単な事などが特徴 ● Babel の実装が固まり次第 Stage 3 にアプ ライされる予定 (来年ぐらい?) No6: 90s Champion Chris Garrett

Slide 9

Slide 9 text

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";

Slide 10

Slide 10 text

Module Fragments (@__sosukesuzuki) ● Stage 1 ● モジュールをインラインで記述するための文を導入する ● プログラマは複数のファイルにそれぞれモジュールを書く ● Native ESM として実行するとモジュールごとにfetchするのでパフォーマンス上の 懸念がある ● 現代ではバンドルするのが主流だがバンドラの実装コストが高くモジュール構造が ランタイムまで残らず最適化に使うことができない ● 1ファイルに複数のモジュールをバンドラから出力できればそれらの問題を解消で きる ● module “#foo” { export const foo = “foo”; } みたいな構文 ○ (少なくとも Stage 1 になったタイミングでは ) No8: 60s

Slide 11

Slide 11 text

🚨 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

Slide 12

Slide 12 text

Import Assertions (@takanorip) ● インポートするモジュールについてキータイプを明記、インポート時に正しいタイプのファイル がインポートされているか検証する仕組み ● ウェブ上ではファイル拡張子と HTTP Content Typeヘッダーの間には、広くミスマッチが存在 するため、サーバーが予期せず異なる MIMEタイプを提供し予期せずコードが実行されてしま うことを防ぐことが目的 ● 現在はJSON Modulesだけが提案されてるが、 HTML ModulesやCSS Modulesも議論中 No10: 60s

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

ユーザーによる 非同期処理の制御 が可能な 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() の提案あり

Slide 15

Slide 15 text

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"}']

Slide 16

Slide 16 text

● 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)

Slide 17

Slide 17 text

JSON modules (@takanorip) ● import assertionsをベースにJSONモジュールをインポートできるようにする仕組み ● もともとimport assertionsの一部だったが、2020年7月に分割された ● TC39でJSONモジュールを定義することで ECMA262に準拠したすべてのホストで一貫した動 作が保証される ● JSONモジュールにアサーションが必要かどうかはホスト( Node.jsなど)が決定する No15: 60s

Slide 18

Slide 18 text

🧳 proposal-js-module-blocks @_keiya01 ● Stage 2 ● WorkerやWorkletのモジュールを別ファ イルに切り出さなければならないのは不 便 ● モジュールをインラインで書くことができ る ● Module Blocks を参照することはできな い ● structured cloneable No16: 60s https://github.com/tc39/proposal-js-module-blocks

Slide 19

Slide 19 text

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 の実装があるので試すのおすすめ

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

Realms (@takanorip) Realmオブジェクト内でJSを仮想化、実行できる仕組み 例 ● WebベースのIDE ● testing/mocking ● ウェブ用のプラグイン(例:スプレッドシート関数) ● サーバーサイドレンダリング ● in-browser transpilation No21: 60s

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

No24: 60s ➢ Promiseを返すAtomics.wait() ➢ 内部的には,waiterListにAgentを追加する処理 を,新しい関数であるdoWait()でラップ ➢ これまで同期的に待つ必要があった Atomics.wait()をpromise-baseに書ける. → Atomics.waitAsync() - @you_5805

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

Export Default From (@Shinyaigeek 🐵) ● default export されているものをnamed exportし直すことができる No28: 30s ● この書き方と同義, 新しいuse caseをカバーするものというよりはより自然な文法を 提供するもの https://github.com/tc39/proposal-export-default-from ● [[ExportName]] は default ではなく name

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

WHATWG URL (@Tsubame_misa) Stage 0 ● WHATGW の URL, URLSearchParamsを ECMAScriptの仕様に導入したい ● Web以外でも動いて嬉しい No30: 30s https://github.com/jasnell/proposal-url

Slide 33

Slide 33 text

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()

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

● Stage1 ● このproposalで追加されるArray.prototype.filterRejectはコールバック関数で実装 されたテストに不合格だったすべての要素からなる新しい配列を生成する ● Array.prototype.filter()はコールバック関数で実装されたテストに合格したすべての 要素からなる新しい配列を生成する ● 類似するメソッドとして、RubyにArray#reject、Underscoreに_.reject、Lodashに _.rejectや_.partitionがある No33: 30s proposal-array-filtering (Forest_Y)

Slide 36

Slide 36 text

現状での再現方法: [...arr].reverse().find() array-find-from-last No34: 30s @progfay Stage 2 Array.prototype.findLast(), Array.prototype.findLastIndex() を追加 ● 不必要なパフォーマンスの低下を招く ● index を取得したい場合には不便 不要なcopy 不要なmutation

Slide 37

Slide 37 text

Array.prototype.uniqueBy() (@autummn_fish)
 ● Stage1
 ● 重複する要素を削除した新しい配列を返すメソッド 
 ● 非プリミティブ型に対応した[...new Set(array)]を返す 
 ● 引数としてNumber,String,Symbolを指定可能 
 ○ 引数をkeyとして重複要素の削除を行う
 ● 関数を引数として渡せる
 ○ 配列の各要素ごとに関数を呼び出し、関数の戻り値に基づいて重複要素を削除する 
 ● 0と-0の区別はない
 ● 空、もしはNullishな値の場合Nullishとして扱われる 
 ● NaNは区別されない
 No35: 30s

Slide 38

Slide 38 text

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)

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

モチベーション ➢ ある非同期関数の呼び出しで,実際に処理が行われる のが同期処理のみである場合,これをタスクキューでは なく即座にコールスタックに追加したい ➢ 下7行目でも可能だが直感的でない アプローチ ➢ Promise.try(f)でこれを達成 No38: 30s → Promise.try() - @you_5805

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

Generator function.sent Meta Property (@Shinyaigeek 🐵) ● Generator関数の中で利用できるメタプロパティ No42: 30s ● yieldを呼べるところでならどこででも参照できる ● 直近で呼ばれたgenerator objectのnext関 数の引数を取得できる ● Generator関数の構造上, 最初に呼ばれるnext関 数の引数にアクセスする方法がない問題に対応し ている https://github.com/tc39/proposal-function.sent

Slide 45

Slide 45 text

Generator Arrow Functions (@oliver_diary) No43: 30s ● generator構文をArrow functionsに追加する提案と `generator` キーワードを追加し `ASI hazard` を避ける提案の2つが上がっている。 ● 現在はArrow functionsのどこにアスタリスクを付けるかに議論が集中しているが、 `() =*>` に軍配が上がりそうな感じではある。 generatorキーワードの提案 アスタリスク記法の候補 現状の有力候補 Stage1

Slide 46

Slide 46 text

🙈 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

Slide 47

Slide 47 text

● 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)

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

Array.prototype.at() (@autummn_fish)
 ● Stage3 ● 負の添字を指定した場合、配列末尾から N番目の要素を返すメソッド ○ Pythonのように添字を扱えてうれしい ○ 現状ではarr[arr.length-N]のように記述できるが冗長だし匿名の値の場合一時変数を用意しなければならない ○ arr.slice(-N)[0]としても記述可能だが、新しい配列を作成してしまう No47: 30s

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

嬉嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 嬉 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 名

Slide 53

Slide 53 text

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)

Slide 54

Slide 54 text

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 ) ```) } }

Slide 55

Slide 55 text

Upsert (@Shinyaigeek 🐵) ● Update + Insert No53: 30s ● Mapに(key, value)を追加する際, 既にkeyが 登録されている時(update)とされていない時 (insert)の処理をかける ● insert, updateは省略可能であり, 省略された 時は何もしない. https://github.com/tc39/proposal-upsert ● しかしinsertが省略されていてかつkeyがMapに 登録されていないときはRuntimeErrorになる

Slide 56

Slide 56 text

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する

Slide 57

Slide 57 text

JavaScript standard library UUID (@oliver_diary) ● 標準ライブラリとしてRFC 4122に基づいたUUIDを提供する提案 ● npmのuuidモジュールがとても多く使われてる現状と、 RFC 4122に触れたことのない開発者が 車輪 の再発明をした際に衝突のリスクがある観点から、標準化することで 「CSPRNG」と呼ばれる「暗号論的擬似乱数生成器」を強制することができるのがモチベーションとし てある。 No55: 30s 提案されているAPI (crypto interface に追加パターン) 他に考えられる選択肢 (メソッドをグローバルに公開パターン ) crypto名前空間に含めることでCSPRNGを使用してUUIDを生成するという 要件を強調している Stage1

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

WeakRefs (@likr) ● Stage 4 (2020年7月)、ES2021 ● GCに回収されても良いような弱参照を実現 ○ キャッシュ機構の実装 ○ destructor(WebAssembly向け) ● WeakRef class ● FinalizationRegistry class 変数、配列、 オブジェクト 弱参照 変数、配列、 オブジェクト オブジェクト オブジェクト GC対象外 弱参照 オブジェクト オブジェクト GC対象 No1: 90s DEMO

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

import() ES2020 ● ESMを動的にimport (dynamic import) ● 引数にmoduleのpath渡す ● 非同期関数で、結果を resolve するPromiseを返す ● named exportはnameがkey ● default exportは”default”が key @arayaryoma No4: 30s DEMO