Slide 1

Slide 1 text

Node学園 39時限目 ES2022の新機能 Author: Masaki Suzuki @makky12

Slide 2

Slide 2 text

自己紹介 • 名前:鈴木 正樹 (Masaki Suzuki) • 在住:愛知県半田市 • 職業:フリーランスエンジニア • 得意分野:サーバーレスアプリのバックエンド(アーキ構築/設計/開発など) • 技術: • AWS/Serverless Framework/Terraform/AWS CDK/サーバーレス全般 • Node.js/TypeScript/Jest/Next.js/Haxe/GCP/Azure • 各種イベント・SNS・ブログでのクラウド普及活動(個人的に) • SNS: http://makky12.hatenablog.com/ https://github.com/smt7174 @makky12 (SUZUKI Masaki@クラウドエンジニア) 名古屋市 豊橋市 Node学園 39時限目

Slide 3

Slide 3 text

本日紹介する新機能 • クラス関連の新機能 • 基本機能 • プライベート要素の有無判定(Ergonomic brand checks for private fields) • クラス以外の新機能 • Top-level await • .at() method on the built-in indexables • Error.cause property • RegExp Match Indices • Object.hasOwn Node学園 39時限目

Slide 4

Slide 4 text

参考資料・サイト • 【参考情報】 • node.green • 【ブログ】 • JavaScriptの次の仕様ES2022の新機能まとめ • 【JavaScript】ES2022の新機能 • 【JavaScript】ES2022で正式採用される機能について 本日の発表資料は、以下の場所で公開してます • https://speakerdeck.com/smt7174/es2022no Node学園 39時限目

Slide 5

Slide 5 text

Node学園 39時限目 クラス関連の新機能

Slide 6

Slide 6 text

クラス関連 • クラス関連の新機能として、下記に正式対応した関数 • クラスフィールドの作成 • 静的(static)な要素の作成 • 静的メソッド/静的フィールドどちらも作成可能 • privateな要素の作成 • これもprivateメソッド/privateフィールドどちらも作成可能 • チームでのルール決めでの対応が不要に • クラスの基本的な部分が、やっと普通に使えるようになった感じ • protectedなど、未対応な部分もあるが… Node学園 39時限目

Slide 7

Slide 7 text

クラス関連(ソースコード) Node学園 39時限目 class A { // クラスフィールド x = 1; // publicなクラスフィールド static sx = 2; // staticをつけると静的(static)フィールドに #y = 3; // #をつけるとprivateなクラスフィールドに static #sy = 4; // privateな静的フィールドも作成可能 constructor() {} // クラスメソッド publicFunc() {} static staticPublicFunc() {} // staticをつけると静的(static) メソッドに #privateFunc() {} // #をつけると静的(static) メソッドに static #staticPrivateFunc() {} // privateな静的(static) メソッド }

Slide 8

Slide 8 text

クラス関連2 • privateな要素の存在有無を「in」でチェックできる • クラスレベルで判定する • 該当クラスのprivateな要素を持っているか判定 • 主な使用用途は、インスタンスの等価チェック? • a instanceof b みたいな使用方法 • 今のところ、良い使用用途がいまいち不明… • 今回クラスフィールド対応が追加されたのもあるので Node学園 39時限目 // ソースコード class A { #x = 1; constructor(x = null) { if (x) #x = x; } static isA(obj) { return #x in obj; } } class B { #x = 1; constructor() {} } console.log(A.isA(new A())); // true console.log(A.isA(new B())); // false console.log(A.isA(new A(2))); // true(値そのものは問わない)

Slide 9

Slide 9 text

Node学園 39時限目 クラス以外の新機能

Slide 10

Slide 10 text

Top-level await • 最上位ソースのみ、直接awaitすることができる • async, Promise.then()などが不要に • モジュールファイルのみ対応(*.mjsなど) • あくまで「最上位ソース」のみが対象 • 関数内などでは、今まで通りasyncが必要 • asyncが完全に不要になったわけではない Node学園 39時限目 // ソースコード //これはNG(関数など最上位ソース以外は、asyncが必要) function badSampleAsync() { return await SampleFuncAsync(); } //これはOK const result = await badSampleAsync(); console.log(result);

Slide 11

Slide 11 text

.at() method on the built-in indexables • 変数.at(index)で、変数[index]の要素にアクセスできる • 文字列、または配列が対象 • indexに負数を指定することで、末尾からの要素を指定できる。(-1が末尾要素) • String.substr(index)と同じ • 末尾要素を指定するのが簡単になった • array[array.length - 1] みたいな指定が不要になった Node学園 39時限目 // ソースコード const str = ‘abcdefg’; const array = [‘hoge’, ‘fuga’, ‘piyo’]; // これは今までもできた console.log(str.at(0)); // a console.log(array.at(1)); // fuga // 負数の指定は.at()からできるようになった console.log(str.at(-3)); // e console.log(array.at(-1)); // piyo

Slide 12

Slide 12 text

Error.cause property • Errorクラスに発生源をたどるプロパティ「cause」が追加された • 「cause」プロパティ自体はオプショナル • 親子関係(=依存関係)があるコードで、エラーの発生源をたどるのに便利 • 「error.cause」プロパティで、発生源のエラー(Error)を参照できる • 子孫要素が多くなると、複数のcauseをたどる必要がある • 「error.cause.cause.cause…」のような感じ • 発生源のエラーを見つける専用の関数などを用意した方が良いかも • そもそも、そこまで依存関係が多いこと自体が問題かもしれないが… Node学園 39時限目

Slide 13

Slide 13 text

Error.cause property(ソースコード) Node学園 39時限目 function parent() { try { child(); } catch (e) { // ここのeはchild()からthrowされたもの。 console.log(`e is ${e.message}`); console.log(e.cause.message); } } function child() { try { grandChild(); } catch (e) { // ここのeはgrandChild()からthrowされたもの。 // 発生源にe(=grandChild Error)を指定 throw new Error("child Error", {cause: e}); } } function grandChild() { // ここがエラー発生源 throw new Error("grandChild Error",); } parent(); // 結果はこうなる e is child Error // console.log(`e is ${e.message}`)の結果 grandChild Error // console.log(e.cause.message)の結果

Slide 14

Slide 14 text

RegExp Match Indices • 正規表現パターンマッチングで一致文字の開始&終了位置を取得できる • 「d」フラグを付けることで可能 • 「indices」プロパティ(配列)のindex:0に配列形式で格納される • indices:[[開始位置, 終了位置]] のような感じ • 終了位置は、一致文字列の最終文字のindex+1が入る。(String.slice()の引数と同じ) • キャプチャグループがある場合、indices[1] 以降に同様の形式で格納される Node学園 39時限目 // ソースコード // キャプチャグループなし const result = /cd/d.exec(‘abcdefabcdefg’); console.log(result.indices); // [ [2, 4], groups: undefined ] // キャプチャグループあり const result = /cd(ef)/d.exec(‘abcdefabcdefg’); console.log(result.indices); // [ [2, 6], [4, 6], groups: undefined ]

Slide 15

Slide 15 text

Object.hasOwn • Object.hasOwn(obj, key)でオブジェクトが該当キーを持っているかを確認できる。 • 挙動自体はObject.hasOwnProperty(obj, key)と同じ • Object.prototype.hasOwnProperty.call(obj, key)のショートハンド • 上記指定だと長いので、そのためかと思われる • Object.hasOwnProperty()によるプロトタイプ汚染問題の対応もある Node学園 39時限目 // ソースコード const obj ={ x: 10, y: 20, }; console.log(Object.hasOwn(obj, ‘x’)); // true console.log(Object.hasOwn(obj, ‘z’)); // false

Slide 16

Slide 16 text

まとめ(個人的な感想) • クラスに関しては「やっと普通に使えるようになった」感じ • 特にクラスフィールド、private要素あたり • private要素に関しては、チームでのルール決めがこれで不要になった • (_から始めるのはprivateな扱い…など) • クラス以外に関しては「大きな変更はないが、地味な部分で便利になった」印象 • 去年の発表(「Node.js16の新機能」)と全く同じだな… • でも個人的に、top-level-awaitやxxx.at(index)はありがたいという感想 Node学園 39時限目

Slide 17

Slide 17 text

以上です ご清聴ありがとうございました Node学園 39時限目