JavaScript: Öffentliche und private Klassenfelder

Mehrere Vorschläge erweitern die vorhandene Klassensyntax in JavaScript um neue Funktionen. In diesem Artikel wird die neue Syntax für öffentliche Klassenfelder in V8 v7.2 und Chrome 72 sowie für bevorstehende private Felder erläutert.


Hier ist ein Beispiel für den Code, der die ZunehmendeCounter- Klasse instanziiert:


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 beim Zugriff auf value ein Code ausgeführt wird (Ausgabe einer Nachricht an das Protokoll), bevor der Wert zurückgegeben wird. Fragen Sie sich nun: Wie würden Sie diese Klasse in JavaScript implementieren?


ES2015 Klassen


Im Folgenden finden Sie ein Beispiel dafür, wie die ZunehmendeCounter- Klasse 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 bietet einen Getter- Wert und eine Methode zum Inkrementieren eines Werts in einem Prototyp. Seltsamerweise verfügt die Klasse über einen Konstruktor, der die Eigenschaft _count initiiert und ihren Anfangswert auf 0 setzt. Jetzt verwenden wir das Unterstrichpräfix, um anzugeben, dass _count nicht direkt außerhalb der Klasse verwendet werden soll, 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 

Klasse öffentliche Felder


Neue Syntax für öffentliche Felder vereinfacht die Klassendefinition:


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

Die Eigenschaft _count wird jetzt am Anfang der Klasse kurz deklariert. Wir brauchen keinen Konstruktor mehr, nur um einige Felder zu definieren. Großartig!


_Count ist jedoch immer noch ein öffentliches Eigentum. In diesem speziellen Beispiel möchten wir verhindern, dass direkt auf dieses Feld zugegriffen wird.


Private Klassenfelder


Hier kommen private Felder zur Rettung. Die neue Syntax für private Felder ähnelt der Syntax für öffentliche Felder, außer dass Sie sie mit dem Symbol # als privat markieren . Sie können denken, 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


Die Klassenfeldsyntax kann verwendet werden, um öffentliche und private statische Eigenschaften und Methoden zu erstellen, wie unten gezeigt:


 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 Arbeit mit Unterklassen


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


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

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


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

Es gibt eine Menge Boilerplate-Code, nur um anzuzeigen, dass Katzen nicht wirklich gerne ein Bad nehmen. Glücklicherweise macht die neue Klassenfeldsyntax die Notwendigkeit überflüssig, diesen Konstruktor mit einem umständlichen Aufruf von super () zu definieren :


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

Insgesamt


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

Source: https://habr.com/ru/post/de438202/


All Articles