質問の歴史:
静的プロパティとメソッドは、ES6以降のJavaScriptのクラスで登場しましたが、これらの要素の厳格な型付けはTypeScriptのおかげで可能になりました。動的なJavaScriptでは、クラスの静的要素は非静的な要素と同じ型ですが、TypeScriptは静的メンバーを考慮に入れて型の安全性とクラスの構造を追加することを許可します。
問題:
静的プロパティとメソッドはクラスそのものに属し、そのインスタンスには属しません。しかし、多くの開発者はインスタンスの型付け(thisまたはコンストラクタを介して)をクラスそのもののオブジェクトとしての型付けと混同することがあります。これは、メソッド内で静的フィールドにアクセスする際や継承時にエラーを引き起こすことがあります。
解決策:
TypeScriptでは、静的メンバーは非静的メンバーとは別に型付けされます:
コードの例:
class User { static count: number = 0; name: string; constructor(name: string) { this.name = name; User.count++; } static getCount(): number { return User.count; } } function createUserClass(): typeof User { return User; }
主な特徴:
静的メソッドはクラスの非静的プロパティに直接アクセスできますか?
いいえ、静的メソッドはthisを介して非静的プロパティにアクセスすることができません。なぜなら、thisはクラス自体を指すからです(コンストラクタ)。非静的プロパティにアクセスするには、オブジェクトのインスタンスを操作する必要があります。
class Demo { static demoStatic() { // this.value; // エラー — valueはstaticではありません } }
クラスのインスタンスを介して静的プロパティにアクセスできますか?
いいえ、静的プロパティはクラス自体の名前を介してのみアクセス可能で、インスタンスを介してはアクセスできません:
const u = new User('Max'); console.log(u.count); // エラー console.log(User.count); // OK
クラスの継承時に静的メソッドをオーバーライドできますか?
はい、静的メソッドは継承され、オーバーライドすることができ、それは期待通りに機能します:
class Animal { static who() { return 'Animal'; } } class Dog extends Animal { static who() { return 'Dog'; } } console.log(Dog.who()); // 'Dog'
開発者が作成されたインスタンスのカウントを通常のインスタンスプロパティとして保持するのではなく、staticとして保持します。オブジェクトが作成されるたびにフィールドが増加しますが、クラスのすべてのオブジェクトに対して同期されません。
利点:
欠点:
すべてのオブジェクトのカウントを保持するためにstatic countを使用し、コンストラクタ内での正しい増加とカウントを取得するための静的メソッドを使用します。
利点:
欠点: