ES 2022プレビュー:2021年から10エキサイティングなJavaScript言語機能


JavaScriptはすぐに進化する.2021年、いくつかproposals ステージ4に移動しましたTC39 process とES 2022に含まれます.JavaScriptに次の機能を追加します.
クラスとインスタンス
  • プライベートインスタンスフィールド、メソッド、アクセサー
  • プライベートフィールドの存在チェック
  • 静的クラスフィールド
  • プライベート静的クラスのフィールドとメソッド
  • 静的クラス初期化ブロック
  • モジュール読み込み
  • トップレベルawait
  • 組み込みオブジェクト
  • エラー.cause
  • array , string , type array :.at()
  • 対象:.hasOwn()
  • 正規表現:マッチ.indices (d ' フラグ
  • このブログ記事は各機能について説明し、どのように使用できるかの例を示し、現在のブラウザとノードを見ています.JSサポート(2021年12月現在).始めましょう

    プライベートインスタンスフィールド、メソッド、アクセサー


    カプセル化はオブジェクト指向プログラミングのコア原則の一つです.これは通常、private or public .
    プライベートインスタンスフィールド、メソッド、アクセサーの特徴1 , 2 ] JavaScriptにハード可視性の制限を追加します.The # Prefixフィールド、メソッド、またはアクセサーをプライベートクラスとしてマークします.つまり、インスタンス自体の外部からアクセスできません.
    ここで、プライベートフィールドとメソッドの例ですアクセサも同様に動作します.
    class Example {
      #value;
    
      constructor(value) {
        this.#value = value;
      }
    
      #calc() {
        return this.#value * 10;
      }
    
      print() {
        console.log(this.#calc());
      }
    }
    
    const object = new Example(5);
    console.log(object.#value);    // SyntaxError
    console.log(object.#calc());   // SyntaxError
    object.print();                // 50
    
    Most browsers (2020年12月使用:~ 90 %)、およびノード.JS 12 +サポートプライベートインスタンスフィールド.The support for private methods and accessors is more limited in browsers (2021年12月使用:~ 80 %).ノード.jsはバージョン14.6以降の機能をサポートしています.あなたはtranspile your code with Babel 直接サポートしていない環境でプライベートクラスのフィールドとメソッドを使用するには.

    プライベートフィールドの存在チェック


    オブジェクトの既存の非公開フィールドにアクセスしようとすると、例外がスローされるため、オブジェクトが指定されたプライベートフィールドを持っているかどうかを確認できます.The in operator can be used to check if a private field is available on an object :
    class Example {
      #field
    
      static isExampleInstance(object) {
        return #field in object;
      }
    }
    
    The browser support for using the in operator on private fields 制限されています.ノード.jsはバージョン16.4以降の機能をサポートします.あなたはtranspile usages of the in operator for private fields with Babel .

    静的クラスフィールド


    Static class fields クラスオブジェクトにプロパティを追加する便利な表記法です.
    // without static class fields:
    class Customer {
      // ...
    }
    Customer.idCounter = 1;
    
    // with static class fields:
    class Customer {
      static idCounter = 1;
      // ...
    }
    
    Most browsers (2020年12月使用:~ 90 %)、およびノード.JS 12 +パブリッククラスのフィールドをサポートします.

    プライベート静的クラスのフィールドとメソッド


    プライベートインスタンスフィールドとメソッドと同様に、カプセル化と可視性の制限はクラスレベルで有用です.The private static methods and fields feature クラスレベルのフィールドとメソッドを使用して# プレフィックス
    class Customer {
      static #idCounter = 1; // static private
    
      static #getNextId() { // static private
        return Customer.#idCounter++;
      }
    
      #id; // instance private
    
      constructor() {
        this.#id = Customer.#getNextId();
      }
    
      toString() {
        return `c${this.#id}`;
      }
    }
    
    const customers = [new Customer(), new Customer()];
    console.log(customers.join(' ')); // c1 c2
    
    ブラウザとノード.JSサポートは、上記のプライベートインスタンスフィールドとメソッドに似ています.

    静的クラス初期化ブロック


    静的クラスフィールドに対して、より複雑な初期化作業を行うためには、必要か便利です.上記からのプライベート静的フィールドについては、プライベートフィールドがそれ以外の場合にアクセスできないため、この初期化はクラス内で行われなければなりません.
    The static initializer blocks feature クラス定義評価中にコードを実行するメカニズムを提供します.ブロックステートメントのコードstatic キーワードを初期化するときに実行されます
    class Example {
      static propertyA;
      static #propertyB; // private
    
      static { // static initializer block
        try {
          const json = JSON.parse(fs.readFileSync('example.json', 'utf8'));
          this.propertyA = json.someProperty;
          this.#propertyB = json.anotherProperty;
        } catch (error) {
          this.propertyA = 'default1';
          this.#propertyB = 'default2';
        }
      }
    
      static print() {
        console.log(Example.propertyA);
        console.log(Example.#propertyB);
      }
    }
    
    Example.print();
    
    The browser support for static class initialization blocks 制限されています.ノード.jsはバージョン16.4以降の機能をサポートします.あなたはtranspile code with static initializer blocks with Babel .

    トップレベル


    非同期関数とawait キーワードは、ES 2017約束での作業を簡素化するために導入されました.しかしawait 内部でのみ使用できますasync 関数.
    The top-level await feature for ES modules 使いやすくするawait CLIスクリプトで.mjs ソースとzx ), そして、ダイナミックなインポートとデータ読み込みのために.それはawait モジュールローダへの機能await ) 積まれる.
    以下に例を示します.
    // load-attribute.mjs 
    // with top-level await
    const data = await (await fetch("https://some.url")).text();
    export const attribute = JSON.parse(data).someAttribute;
    
    // main.mjs 
    // loaded after load-attribute.mjs is fully loaded
    // and its exports are available
    import { attribute } from "./load-attribute.mjs";
    console.log(attribute);
    
    待つトップレベルsupported on modern browsers (2021年12月使用:~ 80 %)、ノード.JS 14.8 +.これはESモジュールだけで利用可能です.そして、CommonJSモジュールがトップレベルをサポートするのを待つことは疑います.トップレベルコードawait のような古いブラウザーをサポートするために、バンドルリングフェーズ中にトランスポートすることができますWebpack 5 experiments.topLevelAwait = true .

    エラー:.原因


    エラーはしばしば意味のあるメッセージを提供し、エラーコンテキストを記録するためにラップされます.しかし、これは元のエラーが失われることを意味します.ログエラーとデバッグ目的のために元のエラーをアタッチすることが望ましい.
    The error cause feature オリジナルエラーをラッピングエラーにアタッチする標準的な方法を提供します.これはcause オプションError コンストラクタとcause 元のエラーを取得するフィールド.
    const load = async (userId) => {
      try {
        return await fetch(`https://service/api/user/${userId}`);
      } catch (error) {
        throw new Error(
          `Loading data for user with id ${userId} failed`, 
          { cause: error }
        );
      }
    }
    
    try {
      const userData = await load(3);
      // ...
    } catch (error) {
      console.log(error); // Error: Loading data for user with id 3 failed
      console.log(error.cause); // TypeError: Failed to fetch
    }
    
    The current browser support for the error clause feature 制限されています.ノード.jsはバージョン16.9以降の機能をサポートします.あなたはerror cause polyfill サポートされていないJSの環境でも、今日の機能を使用して起動します.

    配列、文字列、および型。at ()


    配列や文字列の末尾から要素を取得するには、通常、配列の長さから減算します.let lastElement = anArray[anArray.length - 1] . これは、配列が一時変数に格納され、シームレスな連鎖を防ぐ必要があります.
    The .at() feature 最初の要素(正のインデックス)または文字列の末尾(負のインデックス)または一時変数のない配列から要素を取得する方法を提供します.
    const getExampleValue = () => 'abcdefghi';
    
    console.log(getExampleValue().at(2));    // c
    console.log(getExampleValue()[2]);       // c
    
    const temp = getExampleValue();
    console.log(temp[temp.length - 2]);      // h
    console.log(getExampleValue().at(-2));   // h - no temp var needed
    
    The browser support for the .at feature は現在制限されています( DEC 2021の使用:~ 70 % ).JS 16.6 +.あなたは.at() polyfill from Core JS その間.

    対象:hasown ()


    The Object.hasOwn feature プロパティがオブジェクトに直接設定されているかどうかを確認する、より簡潔で堅牢な方法です.それは、使用に好ましい選択肢ですhasOwnProperty :
    const example = {
      property: '123'
    };
    
    console.log(Object.prototype.hasOwnProperty.call(example, 'property'));
    console.log(Object.hasOwn(example, 'property')); // preferred
    
    The browser support is currently limited (2020年12月使用:~ 70 %)、使用するノードhasOwn 直接.その間に、AがありますCore JS polyfill for hasOwn .

    regexp :インデックスをマッチする


    既定では、正規表現は一致するテキストの開始インデックスを記録しますが、その終了インデックスではなく、キャプチャグループの開始インデックスと終了インデックスとは一致しません.テキストエディタの構文や検索結果の強調表示などのユースケースでは、正規表現マッチの一部としてキャプチャグループのマッチインデックスを持つことができます.
    regexp match indices feature ('d' flag) , マッチとキャプチャグループのインデックスはindices 正規表現の結果のArrayプロパティです.
    マッチしたテキスト位置とマッチインデックス位置は同じです、例えば、マッチしたテキストはマッチ配列とインデックス配列の最初の値です.名前付きキャプチャグループのインデックスはindices.groups .
    以下に例を示します.
    const text = "Let's match one:1.";
    const regexp = /match\s(?<word>\w+):(?<digit>\d)/gd;
    
    for (const match of text.matchAll(regexp)) {
        console.log(match);
    }
    
    上の例のコードには次の出力があります.
    [
      'match one:1',
      'one',
      '1',
      index: 6,
      input: "Let's match one:1.",
      groups: { word: 'one', digit: '1' },
      indices: {
        0: [6,17],
        1: [12,15],
        2: [16,17],
        groups: { 
          digit: [16, 17],
          word: [12, 15]
        }
      }
    ]
    
    The browser support for the RegExp match indices feature is currently limited (2021年12月使用:~ 80 %).ノードで.JSは、機能を有効にすることができます--harmony-regexp-match-indices フラグではなくデフォルトで無効にする.あなたはRegExp match indices polyfill その間.

    結論


    2021年からの新しいJavaScriptは、開発をより便利で堅牢にするのを助けます、そして、それらの大部分はすでに最新のブラウザーとノードで働きます.js環境.
    しかし、多くのユーザーは、ブラウザや環境にはまだES 0022をサポートしています.生産使用のために、目標環境をチェックして、必要に応じてポリフィリングと蒸している使用を使用するか、新しい機能を使用する前に少し長く待つ必要があります.
    2022年にハッピーコーディング!