web-dev-qa-db-fra.com

Comment utiliser une variable statique dans la classe ES6?

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? 

6
Caesium133

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.

5
T.J. Crowder

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;
  }
};
1
estus

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()); 
1
mpm

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

0
Farooq Hanif