J'essaie d'utiliser une variable statique dans es6. J'aimerais déclarer une variable statique count
dans la classe Animal
et l'augmenter. Cependant, je ne pouvais pas déclarer une variable statique via static count = 0;
, alors j'ai essayé d'une autre manière comme ceci:
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
Je m'attendais à ce que console.log(Animal.getCount());
soit 1
, mais cela ne fonctionne pas. Comment déclarer une variable statique et la modifier en appelant une méthode?
Votre classe n'a pas de variables statiques (si par variable statique, vous voulez dire propriété statique). getCount
renvoie NaN
(après avoir appelé increaseCount
) car Animal
n'a pas de propriété count
au départ. Alors increaseCount
fait undefined + 1
qui est NaN
. Les instances créées par new Animal
ont une propriété count
au départ, mais Animal
ne le fait pas tant que vous n'avez pas appelé increaseCount
. this
au sein d'une méthode static
fait référence à la classe Animal
(fonction du constructeur) elle-même (si vous l'appelez via Animal.methodName(...)
).
Vous pouvez donner à Animal
une propriété count
:
Animal.count = 0;
Exemple en direct:
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());
Avec la proposition de champs de classe statique (actuellement à l'étape 3), vous pouvez le faire de manière déclarative avec static count = 0;
dans Animal
. Exemple en direct (la configuration de Babel dans Stipp Snippets semble la prendre en charge):
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());
Note secondaire: Utiliser this
au sein d'une méthode statique pour faire référence à la classe (fonction constructeur) est un peu délicat s'il existe des sous-classes, car, par exemple, si vous aviez:
class Mammal extends Animal {}
et alors
Mammal.increaseCount();
this
dans increaseCount
(dont il hérite de Animal
) fait référence à Mammal
et non Animal
.
Si vous voulez ce comportement, utilisez this
. Sinon, utilisez Animal
dans ces méthodes static
.
Comme mentionné dans d'autres réponses, this.count
fait référence à la propriété instance dans constructor
. Animal.count
doit être défini pour que la propriété static soit initialisée.
La proposition de champs de classe fournit le sucre syntaxique pour Animal.count = 0
disponible avec les transpileurs (Babel, etc.):
class Animal {
static count = 0;
...
}
Une alternative dans ES6 consiste à utiliser des valeurs initiales, dans ce cas, la valeur initiale de Animal.count
n'a pas besoin d'être définie explicitement, par exemple:
class Animal {
static increaseCount() {
this.count = this.getCount() + 1;
}
static getCount() {
return this.count || 0;
}
}
Les méthodes d'accesseur ne sont pas les bienvenues dans les classes JavaScript - voici à quoi servent les descripteurs getter/setter:
class Animal {
static increaseCount() {
this._count += 1;
}
static get count() {
return this._count || 0;
}
static set count(v) {
this._count = v;
}
}
Les classes statiques uniquement sont considérées comme des anti-modèles en JavaScript, car aucun état ni aucun trait spécifique aux classes ne sont utilisés. Dans le cas où il n'y aurait qu'un cas, l'objet simple devrait être utilisé (à moins qu'il n'y ait d'autres préoccupations qui pourraient bénéficier de class
):
const animal = {
increaseCount() {
this._count += 1;
},
get count() {
return this._count || 0;
},
set count(v) {
this._count = v;
}
};
Pour définir une variable statique, définissez-la sur l'objet Animal lui-même. Pour l'instant, en Javascript, vous ne pouvez pas déclarer directement des propriétés statiques à l'intérieur de classes, comme vous pouvez déclarer des méthodes statiques.
class Animal {
constructor() {
}
static increaseCount() {
this.count += 1;
}
static getCount() {
return this.count;
}
}
Animal.count = 0;
console.log(Animal.increaseCount());
console.log(Animal.getCount());
Les propriétés statiques côté classe et les propriétés de données prototypes doivent être définies en dehors de la déclaration 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