JavaScript: Öffentliche und private Klassenfelder

Ursprünglicher Autor: Mathias Bynens
  • Übersetzung

Mehrere Sätze erweitern die bestehende Klassensyntax in JavaScript um neue Funktionen. In diesem Artikel werden die neue Klasse öffentlicher Feldsyntax in V8 v7.2 und Chrome 72 sowie die kommenden privaten Felder erläutert.


Hier ist ein Beispiel für den Code, der eine Instanz der Klasse ZunehmendeCounter erstellt :


const counter = new IncreasingCounter();
counter.value;
// logs 'Getting the current value!'
// → 0
counter.increment();
counter.value;
// logs 'Getting the current value!'
// → 1

Beachten Sie, dass der Zugriff auf value etwas Code ausführt (Ausgabe einer Nachricht an das Protokoll), bevor Sie einen Wert zurückgeben. Fragen Sie sich jetzt: Wie würden Sie diese Klasse in JavaScript implementieren?


ES2015 Klassen


Im Folgenden finden Sie ein Beispiel dafür, wie die Klasse " ZunehmendeCounter" mithilfe der ES2015-Syntax implementiert werden kann:


class IncreasingCounter {
  constructor() {
    this._count = 0;
  }
  get value() {
    console.log('Getting the current value!');
    return this._count;
  }
  increment() {
    this._count++;
  }
}

Die Klasse stellt einen Getter- Wert und eine Methode zum Inkrementieren des Werts im Prototyp bereit . Merkwürdiger ist , dass die Klasse über einen Konstruktor verfügt, der die _count- Eigenschaft auslöst und ihren Anfangswert auf 0 setzt. Wir verwenden jetzt das Unterstrich-Präfix, um anzugeben, dass _count nicht direkt außerhalb der Klasse verwendet werden sollte. Dies ist jedoch nur eine Konvention. In Wirklichkeit ist dies kein Privateigentum, und diese Semantik ist nicht in der Sprache selbst definiert.


const counter = new IncreasingCounter();
counter.value;
// logs 'Getting the current value!'
// → 0
// Nothing stops people from reading or messing with the
// `_count` instance property. 
counter._count;
// → 0
counter._count = 42;
counter.value;
// logs 'Getting the current value!'
// → 42

Öffentliche Klassenfelder


Mit der neuen Syntax für öffentliche Felder können Sie die Definition einer Klasse vereinfachen:


class IncreasingCounter {
  _count = 0;
  get value() {
    console.log('Getting the current value!');
    return this._count;
  }
  increment() {
    this._count++;
  }
}

Die _count -Eigenschaft wird nun am Anfang einer Klasse kurz und knapp deklariert. Wir brauchen keinen Konstruktor mehr, nur um einige Felder zu definieren. Großartig!


Dennoch _count - noch öffentliches Eigentum. In diesem speziellen Beispiel möchten wir den direkten Zugriff auf dieses Feld verhindern.


Private Klassenfelder


Hier kommen private Felder zur Rettung. Die neue Syntax für private Felder ähnelt der Syntax öffentlicher Felder, außer dass Sie sie mit dem # -Symbol als privat kennzeichnen . Sie denken vielleicht, dass # nur ein Teil des Feldnamens ist:


class IncreasingCounter {
  #count = 0;
  get value() {
    console.log('Getting the current value!');
    return this.#count;
  }
  increment() {
    this.#count++;
  }
}

Private Felder sind außerhalb des Klassenkörpers nicht verfügbar:


const counter = new IncreasingCounter();
counter.#count;
// → SyntaxError
counter.#count = 42;
// → SyntaxError

Statische Eigenschaften


Mit der Klassenfeldsyntax können Sie öffentliche und private statische Eigenschaften und Methoden erstellen (siehe unten):


class FakeMath {
  // `PI` is a static public property.
  static PI = 22 / 7; // Close enough.
  // `#totallyRandomNumber` is a static private property.
  static #totallyRandomNumber = 4;
  // `#computeRandomNumber` is a static private method.
  static #computeRandomNumber() {
    return FakeMath.#totallyRandomNumber;
  }
  // `random` is a static public method (ES2015 syntax)
  // that consumes `#computeRandomNumber`.
  static random() {
    console.log('I heard you like random numbers…')
    return FakeMath.#computeRandomNumber();
  }
}
FakeMath.PI;
// → 3.142857142857143
FakeMath.random();
// logs 'I heard you like random numbers…'
// → 4
FakeMath.#totallyRandomNumber;
// → SyntaxError
FakeMath.#computeRandomNumber();
// → SyntaxError

Vereinfachen Sie die Unterklassen


Die Vorteile der neuen Klassenfeldsyntax werden beim Arbeiten mit Unterklassen, die zusätzliche Felder einführen, deutlicher. Stellen Sie sich folgende Grundtierklasse vor :


class Animal {
  constructor(name) {
    this.name = name;
  }
}

Um eine Cat- Unterklasse zu erstellen , die einer Instanz eine neue Eigenschaft hinzufügt, mussten Sie zuvor super () aufrufen, um den Konstruktor der Basis- Animal- Klasse aufzurufen, bevor Sie diese Eigenschaft erstellen:


class Cat extends Animal {
  constructor(name) {
    super(name);
    this.likesBaths = false;
  }
  meow() {
    console.log('Meow!');
  }
}

Es gibt viel Vorlagencode, nur um anzuzeigen, dass Katzen kein Bad nehmen möchten. Glücklicherweise beseitigt die neue Klassenfeldsyntax die Notwendigkeit, diesen Konstruktor mit einem umständlichen super () - Aufruf zu definieren :


class Cat extends Animal {
  likesBaths = false;
  meow() {
    console.log('Meow!');
  }
}

Gesamt


Öffentliche Klassenfelder sind ab V8 v7.2 und Chrome 72 verfügbar. Es ist geplant, bald private Klassenfelder zu veröffentlichen.


Jetzt auch beliebt: