web-dev-qa-db-de.com

Wie verwende ich eine statische Variable in der ES6-Klasse?

Ich versuche eine statische Variable in es6 zu verwenden. Ich möchte eine statische Variable count in der Klasse Animal deklarieren und erhöhen. Ich konnte jedoch keine statische Variable über static count = 0; deklarieren, also habe ich einen anderen Weg versucht:

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

Ich habe console.log(Animal.getCount()); erwartet 1, aber es funktioniert nicht. Wie deklariere ich eine statische Variable und modifiziere sie durch Aufruf einer Methode? 

6
Caesium133

Ihre Klasse hat keine statischen Variablen (wenn Sie mit statischer Variable eine statische Eigenschaft meinen). getCount gibt NaN zurück (nachdem Sie increaseCount aufgerufen haben), da Animal zunächst keine count-Eigenschaft hat. Dann macht increaseCountundefined + 1, was NaN ist. Instanzen, die von new Animal erstellt wurden, haben anfangs eine count-Eigenschaft, Animal selbst jedoch erst, wenn Sie increaseCount aufrufen. this innerhalb einer static-Methode bezieht sich auf die Animal-Klasse (Konstruktorfunktion) selbst (wenn Sie sie über Animal.methodName(...) aufrufen).

Sie könnten Animal eine count-Eigenschaft geben:

Animal.count = 0;

Live-Beispiel:

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

Mit dem static Klassenfeld-Vorschlag (derzeit in Stufe 3) können Sie dies mit static count = 0; in Animal deklarativ tun. Live-Beispiel (Die Babel-Konfiguration von Stack Snippets scheint dies zu unterstützen):

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


Randbemerkung: Die Verwendung von this innerhalb einer statischen Methode zum Verweisen auf die Klasse (Konstruktorfunktion) ist etwas kompliziert, wenn Subklassen vorhanden sind, weil zum Beispiel:

class Mammal extends Animal {}

und dann

Mammal.increaseCount();

this innerhalb von increaseCount (die er von Animal erbt) verweist auf Mammal, nicht auf Animal.

Wenn Sie wollen dieses Verhalten, _ verwenden, verwenden Sie this. Andernfalls verwenden Sie Animal in diesen static-Methoden.

5
T.J. Crowder

Wie in anderen Antworten erwähnt, bezieht sich this.count auf die instance - Eigenschaft in constructor. Damit die Eigenschaft static initialisiert werden kann, muss Animal.count festgelegt werden.

Vorschlag für Klassenfelder liefert syntaktischen Zucker für Animal.count = 0, der mit Transpillern (Babel usw.) verfügbar ist:

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

Eine Alternative in ES6 ist die Verwendung von Anfangswerten. In diesem Fall muss der Animal.count-Anfangswert nicht explizit festgelegt werden, z.

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

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

Accessor-Methoden sind in JavaScript-Klassen nicht erwünscht. Dafür gibt es Getter-/Setter-Deskriptoren:

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

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

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

Nur statische Klassen werden in JavaScript als Antipattern betrachtet, da ein Zustand oder andere für Klassen spezifische Merkmale nicht verwendet werden. Falls es nur eine Instanz geben sollte, sollte ein einfaches Objekt verwendet werden (es sei denn, es gibt andere Bedenken, die von class profitieren könnten):

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

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

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

Um eine statische Variable festzulegen, setzen Sie sie auf das Objekt Animal selbst. In Javascript können Sie statische Eigenschaften in Klassen jetzt nicht direkt deklarieren, wie statische Methoden.

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

Statische klassenseitige Eigenschaften und Prototypdateneigenschaften müssen außerhalb der ClassBody-Deklaration definiert werden.

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