30代からのプログラミング学び直し!

10年エンジニアやってるけどいまだになんもわからん

JavaScriptのclass定義をインスタンスフィールド構文で今時っぽく書く

JavaScriptのクラス定義の書き方が、ES2022以降に変化したことを知った(遅い)ので、そのまとめです。 主にクラスフィールドの定義を、スタイリッシュに分かりやすく書けるようになったみたいです。

パブリッククラスフィールド

パブリッククラスフィールド - JavaScript | MDN

従来

クラスのインスタンスに対してフィールド(プロパティ)を定義したい時、従来はコンストラクタやメソッドの中でフィールドを初期化する必要があった。

class Size {
  constructor(w, h) {
    this.width = w;
    this.height = h;
  }
}
現在

コンストラクタの外でインスタンスフィールドを直接初期化できるようになった。(この書き方をしてもコンストラクタの一部として実行されるらしい。)先頭に記述することで、どのフィールドがインスタンスの状態を保持しているかが分かりやすくなった。

class Size {
  width = 0;
  height = 0;
  constructor(w, h) {
    this.width = w;
    this.height = h;
  }
}

プライベートフィールド

プライベートプロパティ - JavaScript | MDN

ES2022以降は、プライベートなインスタンスフィールドが利用できるようになった。フィールドの名前を#から始めると、そのフィールドはクラス本体内では利用可能だが、外からは見えなくなりアクセス・変更できなくなる。 プライベートフィールドを定義したときはゲッター関数も定義しておくのが良い。

class Size {
  #width = 0;
  #height = 0;
  constructor(w, h) {
    this.#width = w;
    this.#height = h;
  }
  get width() {
    return this.#width;
  }
  get height() {
    return this.#height;
  }
}
let size = new Size(100, 200);
console.log(size.width); // => 100
console.log(size.#width); // => アクセスできないので構文エラーになる

静的フィールド

static - JavaScript | MDN

従来

クラスに対して静的フィールドを定義したい場合、クラスを定義した後にクラス本体の外側で静的フィールドを定義していた。

class Size {
  constructor(w, h) {
    this.width = w;
    this.height = h;
  }
}
Size.ZERO = new Size(0, 0); // 静的フィールド定義
現在

パブリックフィールドやプライベートフィールドを宣言するときにstaticを使えるようになった。staticを前置すると、インスタンスのプロパティではなくコンストラクタ関数のプロパティとして生成される。

class Size {
  width = 0;
  height = 0;
  static ZERO = new Size(0, 0); // クラス本体中で静的フィールドを定義。Size.ZEROで呼び出す。
  // 以下省略
}

令和っぽいコードを書きたいですな〜!