2022年4月23日

静的(static)プロパティとメソッド

クラス全体にメソッドを割り当てることもできます。このようなメソッドは static(静的) と呼ばれます。

クラス宣言の中では、次のように static キーワードを付けます。

class User {
  static staticMethod() {
    alert(this === User);
  }
}

User.staticMethod(); // true

これは、実際にはプロパティとして直接割り当てるのと同じことをします。:

class User {}

User.staticMethod = function () {
  alert(this === User);
};

User.staticMethod(); // true

User.staticMethod() 内の this の値はクラスコンストラクタ User 自身(“ドットの前のオブジェクト” ルール)です。

通常 static メソッドは、クラスには属するが、特定のオブジェクトには属さない関数を実装するのに使用されます。

例えば、Article オブジェクトがあり、それらを比較するための関数が必要とします。

自然な解決策は、静的メソッド Article.compare を追加することです。:

class Article {
  constructor(title, date) {
    this.title = title;
    this.date = date;
  }

  static compare(articleA, articleB) {
    return articleA.date - articleB.date;
  }
}

// usage
let articles = [
  new Article("Mind", new Date(2019, 1, 1)),
  new Article("Body", new Date(2019, 0, 1)),
  new Article("JavaScript", new Date(2019, 11, 1))
];

articles.sort(Article.compare);

alert( articles[0].title ); // Body

ここでは、Article.compare は記事を比較する手段として、記事の “上位” にいます。記事のメソッドと言うよりはクラス全体のメソッドです。

別の例は、いわゆる “ファクトリー” メソッドです。

記事の作成には複数の方法が必要です:

  1. 与えられたパラメータ(title, date など)による作成
  2. 今日の日付の空の記事の作成

最初の方法はコンストラクタで実装することができます。そして、2 つ目の方法としてはクラスの静的メソッドを作ることができます。

ここでの Article.createTodays() を見てください:

class Article {
  constructor(title, date) {
    this.title = title;
    this.date = date;
  }

  static createTodays() {
    // 思い出してください, this = Article
    return new this("Today's digest", new Date());
  }
}

let article = Article.createTodays();

alert( article.title ); // Todays digest

これで今日のダイジェストを作成する必要があるたびに、Article.createTodays() を呼べます。改めて言いますが、これは記事のメソッドではなく、クラス全体のメソッドです。

静的メソッドは、次のように、データベース関連のクラスでデータベースの検索/保存/削除のためにも使用されます。:

// Article は記事を管理するための特別なクラスと仮定します
// 記事を削除するための static メソッド:
Article.remove({ id: 12345 });

静的プロパティ

A recent addition
This is a recent addition to the language. Examples work in the recent Chrome.

静的プロパティも可能で、通常のクラスプロパティと同じように見えますが、先頭に static が付きます。

class Article {
  static publisher = "Ilya Kantor";
}

alert(Article.publisher); // Ilya Kantor

これは直接 Article に代入するのと同じです。:

Article.publisher = "Ilya Kantor";