web-dev-qa-db-ja.com

ES6クラスで静的変数を使用するにはどうすればよいですか?

Es6で静的変数を使用しようとしています。 countクラスで静的変数Animalを宣言し、増やしたいと思います。ただし、_static count = 0;_を使用して静的変数を宣言できなかったため、次のような別の方法を試しました。

_class Animal {
  constructor() {
    this.count = 0;
  }

  static increaseCount() {
    this.count += 1;
  }

  static getCount() {
    return this.count;
  }
}

console.log(Animal.increaseCount()); // undefined
console.log(Animal.getCount()); // NaN_

console.log(Animal.getCount());が_1_になると予想していましたが、機能しません。静的変数を宣言し、メソッドを呼び出して変更するにはどうすればよいですか?

7
Caesium133

クラスに静的変数がありません(静的変数によって静的プロパティを意味する場合)。 getCountには最初はNaNプロパティがないため、increaseCountAnimalを返します(countを呼び出した後)。次に、increaseCountNaNである_undefined + 1_を実行します。 インスタンス _new Animal_によって作成された最初はcountプロパティがありますが、Animal自体はincreaseCountを呼び出すまで保持されません。 thisメソッド内のstaticは、Animalクラス(コンストラクター関数)自体を参照します(Animal.methodName(...)を介して呼び出した場合)。

Animalcountプロパティを与えることができます:

_Animal.count = 0;
_

実例:

_class Animal {
  constructor() {
  }

  static increaseCount() {
    this.count += 1;
  }

  static getCount() {
    return this.count;
  }
}
Animal.count = 0;

Animal.increaseCount();
console.log(Animal.getCount());
Animal.increaseCount();
console.log(Animal.getCount());_

静的クラスフィールドの提案 (現在Stage 3で)を使用すると、Animalの_static count = 0;_で宣言的に行うことができます。ライブの例(Stack SnippetsのBabel構成がサポートしているようです)

_class Animal {
  constructor() {
  }

  static count = 0;
  
  static increaseCount() {
    this.count += 1;
  }

  static getCount() {
    return this.count;
  }
}

Animal.increaseCount();
console.log(Animal.getCount());
Animal.increaseCount();
console.log(Animal.getCount());_

サイドノート:静的メソッド内でthisを使用してクラス(コンストラクター関数)を参照することは、サブクラスがある場合は少し注意が必要です。

_class Mammal extends Animal {}
_

その後

_Mammal.increaseCount();
_

this内のincreaseCountAnimalから継承)は、Mammalではなく、Animalを指します。

その動作をwantしたい場合は、thisを使用します。そうしない場合は、Animalメソッドでstaticを使用します。

8
T.J. Crowder

他の回答で述べたように、this.countは、constructorinstanceプロパティを参照します。 staticプロパティを初期化するには、Animal.countを設定する必要があります。

クラスフィールドの提案 は、Animal.count = 0トランスパイラーで使用可能(Babelなど):

class Animal {
  static count = 0;
  ...
}

ES6の代替方法は、初期値を使用することです。この場合はAnimal.count初期値を明示的に設定する必要はありません。例:

class Animal {    
  static increaseCount() {
    this.count = this.getCount() + 1;
  }

  static getCount() {
    return this.count || 0;
  }
}

JavaScriptクラスではアクセサメソッドは使用できません-これがゲッター/セッター記述子の目的です:

class Animal {    
  static increaseCount() {
    this._count += 1;
  }

  static get count() {
    return this._count || 0;
  }

  static set count(v) {
    this._count = v;
  }
}

静的のみのクラスは、クラス固有の状態またはその他の特性が使用されないため、JavaScriptではアンチパターンと見なされます。インスタンスが1つしかない場合は、プレーンオブジェクトを使用する必要があります(classの恩恵を受ける可能性のある他の懸念がない限り)。

const animal = {    
  increaseCount() {
    this._count += 1;
  },

  get count() {
    return this._count || 0;
  },

  set count(v) {
    this._count = v;
  }
};
5
Estus Flask

静的変数を設定するには、オブジェクトAnimalに設定します。現在、Javascriptでは、静的メソッドを宣言できるように、クラス内で静的プロパティを直接宣言することはできません。

class Animal {
    constructor() {
    }

    static increaseCount() {
        this.count += 1;
    }

    static getCount() {
        return this.count;
    }
}
Animal.count = 0;
console.log(Animal.increaseCount());
console.log(Animal.getCount()); 
1
mpm

静的なクラス側プロパティとプロトタイプデータプロパティは、ClassBody宣言の外側で定義する必要があります。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes

class Animal {

  static increaseCount() {
    Animal.count += 1;
  }

  static getCount() {
    return Animal.count;
  }
}

Animal.count = 0;

Animal.increaseCount();
console.log(Animal.getCount()); // undefined
0
Farooq Hanif