Heim > Web-Frontend > js-Tutorial > Javascripts neue private Klassenfelder und wie man sie benutzt

Javascripts neue private Klassenfelder und wie man sie benutzt

Joseph Gordon-Levitt
Freigeben: 2025-02-10 14:30:15
Original
778 Leute haben es durchsucht

JavaScript's New Private Class Fields, and How to Use Them

ES6 führt Klassen für JavaScript ein, aber für komplexe Anwendungen können sie zu einfach sein. Klassenfelder (auch als Klasse -Attribut bekannt) sind so konzipiert, dass Konstruktoren mit privaten und statischen Mitgliedern vereinfacht werden. Der Vorschlag erfolgt derzeit in TC39 Phase 3: Kandidatenstufe und wird wahrscheinlich zu ES2019 (ES10) hinzugefügt. Node.js 12, Chrome 74 und Babel unterstützen derzeit private Felder. Bevor wir verstehen, wie Klassenfelder implementiert werden, ist es nützlich, die ES6 -Klasse zu überprüfen. Dieser Artikel wurde im Jahr 2020 aktualisiert. Für ein umfassenderes JavaScript-Wissen finden Sie unser Buch "JavaScript: From Newbie zu Ninja, Second Edition".

Schlüsselpunkte

  • ES6 führt Klassen für JavaScript ein, aber für komplexe Anwendungen können sie zu einfach sein. Die Klassenfelder von ES2019 sollen den Konstruktor mit privaten und statischen Mitgliedern vereinfachen, die zu ES2019 (ES10) hinzugefügt werden können.
  • Die Implementierung der neuen Klassenfelde ermöglicht die Initialisierung öffentlicher Eigenschaften außerhalb eines jeden Konstruktors oben in der Klasse. Wenn der Konstruktor noch benötigt wird, wird der Initialisierer vor seiner Ausführung ausgeführt.
  • Die Klassenfelder in ES2019 ermöglichen es, dass private Klassenfelder mit einem Hash# -Prefix deklariert werden. Dies macht das Feld nur in den inneren Methoden der Klasse zugänglich, nicht von außerhalb der Klasse.
  • Die Verwendung von # zur Darstellung der Privatsphäre in Klassenfeldern wurde kritisiert, vor allem, weil es nicht so intuitiv ist wie private Schlüsselwörter. Das # Symbol ist jedoch außerhalb der Klassendefinition ungültig und stellt sicher, dass die privaten Felder privat bleiben.
  • Der unmittelbare Nutzen von ES2019 -Klassenfeldern ist der Cleaner React -Code. Sie können als Funktion unter Verwendung des ES6 = & GT zugewiesen werden;

es6 Kategorie -Grundlagen

Entwickler aus Sprachen wie C, C#, Java und PHP können durch das objektorientierte Vererbungsmodell von JavaScript verwechselt werden. Daher führte ES6 die Klasse ein. Sie sind hauptsächlich syntaktischer Zucker, bieten aber ein vertrauteres Konzept der objektorientierten Programmierung. Eine Klasse ist eine Objektvorlage , die definiert, wie Objekte dieses Typs sich verhalten. Die folgende Tierklasse definiert allgemeine Tiere (Klassen werden normalerweise in anfänglichen Großbuchstaben dargestellt, um sie von Objekten und anderen Typen zu unterscheiden):

class Animal {

  constructor(name = 'anonymous', legs = 4, noise = 'nothing') {

    this.type = 'animal';
    this.name = name;
    this.legs = legs;
    this.noise = noise;

  }

  speak() {
    console.log(`${this.name} says "${this.noise}"`);
  }

  walk() {
    console.log(`${this.name} walks on ${this.legs} legs`);
  }

}
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Klassenerklärungen werden immer im strengen Modus ausgeführt. Keine Notwendigkeit, "Strikte" hinzuzufügen. Konstruktormethode wird ausgeführt, wenn ein Objekt vom Typ Tier erstellt wird. Es setzt normalerweise erste Eigenschaften und behandelt andere Initialisierungen. Speak () und Walk () sind Instanzmethoden, die mehr Funktionen hinzufügen. Sie können jetzt das neue Schlüsselwort verwenden, um Objekte aus dieser Klasse zu erstellen:

let rex = new Animal('Rex', 4, 'woof');
rex.speak();          // Rex says "woof"
rex.noise = 'growl';
rex.speak();          // Rex says "growl"
Nach dem Login kopieren
Nach dem Login kopieren

Getter und Setter

Setter ist eine spezielle Methode, die nur zum Definieren von Werten verwendet wird. In ähnlicher Weise ist Getter nur eine spezielle Methode für Rückgabewerte. Zum Beispiel:

class Animal {

  constructor(name = 'anonymous', legs = 4, noise = 'nothing') {

    this.type = 'animal';
    this.name = name;
    this.legs = legs;
    this.noise = noise;

  }

  speak() {
    console.log(`${this.name} says "${this.noise}"`);
  }

  walk() {
    console.log(`${this.name} walks on ${this.legs} legs`);
  }

  // setter
  set eats(food) {
    this.food = food;
  }

  // getter
  get dinner() {
    return `${this.name} eats ${this.food || 'nothing'} for dinner.`;
  }

}

let rex = new Animal('Rex', 4, 'woof');
rex.eats = 'anything';
console.log( rex.dinner );  // Rex eats anything for dinner.
Nach dem Login kopieren
Nach dem Login kopieren

Unterklasse oder Unterklasse

Es ist normalerweise möglich, eine Klasse als Basisklasse für eine andere zu verwenden. Die menschliche Klasse kann alle Eigenschaften und Methoden in der Tierklasse unter Verwendung des Extends -Schlüsselworts erben. Eigenschaften und Methoden können nach Bedarf hinzugefügt, entfernt oder geändert werden, um menschliche Objekte einfacher und klarer zu erstellen:

class Animal {

  constructor(name = 'anonymous', legs = 4, noise = 'nothing') {

    this.type = 'animal';
    this.name = name;
    this.legs = legs;
    this.noise = noise;

  }

  speak() {
    console.log(`${this.name} says "${this.noise}"`);
  }

  walk() {
    console.log(`${this.name} walks on ${this.legs} legs`);
  }

}
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Super bezieht sich auf die übergeordnete Klasse, daher ist es normalerweise der erste Anruf im Konstruktor. In diesem Beispiel überschreibt die Methode des menschlichen Speak () die im Tier definierte Methode. Jetzt können Sie eine Instanz des menschlichen Objekts erstellen:

let rex = new Animal('Rex', 4, 'woof');
rex.speak();          // Rex says "woof"
rex.noise = 'growl';
rex.speak();          // Rex says "growl"
Nach dem Login kopieren
Nach dem Login kopieren

statische Methoden und Eigenschaften

Das Definieren von Methoden mit statischen Schlüsselwörtern ermöglicht es, eine Klasse aufgerufen zu werden, ohne eine Objektinstanz zu erstellen. Betrachten Sie Math.PI -Konstanten: Es ist nicht erforderlich, ein Mathematikobjekt zu erstellen, bevor Sie auf PI -Eigenschaften zugreifen. ES6 unterstützt nicht dieselben statischen Eigenschaften wie andere Sprachen, aber die Klassendefinition selbst können Eigenschaften hinzugefügt werden. Zum Beispiel kann die menschliche Klasse angepasst werden, um die Zählung davon zu behalten, wie viele menschliche Objekte erstellt wurden:

class Animal {

  constructor(name = 'anonymous', legs = 4, noise = 'nothing') {

    this.type = 'animal';
    this.name = name;
    this.legs = legs;
    this.noise = noise;

  }

  speak() {
    console.log(`${this.name} says "${this.noise}"`);
  }

  walk() {
    console.log(`${this.name} walks on ${this.legs} legs`);
  }

  // setter
  set eats(food) {
    this.food = food;
  }

  // getter
  get dinner() {
    return `${this.name} eats ${this.food || 'nothing'} for dinner.`;
  }

}

let rex = new Animal('Rex', 4, 'woof');
rex.eats = 'anything';
console.log( rex.dinner );  // Rex eats anything for dinner.
Nach dem Login kopieren
Nach dem Login kopieren
Der statische Zähler der

-Klasse gibt die Anzahl der Menschen entsprechend zurück:

class Human extends Animal {

  constructor(name) {

    // 调用Animal构造函数
    super(name, 2, 'nothing of interest');
    this.type = 'human';

  }

  // 重写Animal.speak
  speak(to) {

    super.speak();
    if (to) console.log(`to ${to}`);

  }

}
Nach dem Login kopieren

ES2019 Klassenfelder ( neu )

Die Implementierung der neuen Klassenfelde ermöglicht die Initialisierung öffentlicher Eigenschaften außerhalb eines jeden Konstruktors oben in der Klasse:

let don = new Human('Don');
don.speak('anyone');        // Don says "nothing of interest" to anyone

don.eats = 'burgers';
console.log( don.dinner );  // Don eats burgers for dinner.
Nach dem Login kopieren

Dies entspricht:

class Human extends Animal {

  constructor(name) {

    // 调用Animal构造函数
    super(name, 2, 'nothing of interest');
    this.type = 'human';

    // 更新Human对象的计数
    Human.count++;

  }

  // 重写Animal.speak
  speak(to) {

    super.speak();
    if (to) console.log(`to ${to}`);

  }

  // 返回人类对象的个数
  static get COUNT() {
    return Human.count;
  }

}

// 类的静态属性本身 - 不是其对象
Human.count = 0;
Nach dem Login kopieren

Wenn Sie den Konstruktor noch benötigen, wird der Initialisierer vor dem Ausführen ausgeführt.

Static Class Field

Im obigen Beispiel werden dem Klassendefinitionsobjekt nach der Definition des Klassenobjekts statische Eigenschaften auf unelegante Weise hinzugefügt. Sie müssen keine Klassenfelder verwenden:

console.log(`Humans defined: ${Human.COUNT}`); // Humans defined: 0

let don = new Human('Don');

console.log(`Humans defined: ${Human.COUNT}`); // Humans defined: 1

let kim = new Human('Kim');

console.log(`Humans defined: ${Human.COUNT}`); // Humans defined: 2
Nach dem Login kopieren

Dies entspricht:

class MyClass {

  a = 1;
  b = 2;
  c = 3;

}
Nach dem Login kopieren

FALTSUMPRISSE -Klassenfeld

Alle Attribute in der Klasse

ES6 sind standardmäßig öffentlich und können außerhalb der -Klasse überprüft oder geändert werden. Im obigen Tierbild kann nichts verhindern, dass das Nahrungsmitteleigenschaften das ESS -Setter annimmt:

class MyClass {

  constructor() {
    this.a = 1;
    this.b = 2;
    this.c = 3;
  }

}
Nach dem Login kopieren
Andere Sprachen ermöglichen normalerweise eine Erklärung privater Attribute. Dies ist in ES6 nicht möglich, daher verwenden Entwickler häufig Unterstriche (_propertyName), Schließungen, Symbole oder Schwächen, um dieses Problem zu lösen. Der Unterstrich gibt Entwicklern einen Hinweis, aber nichts kann sie daran hindern, auf die Immobilie zuzugreifen. In der ES2019 werden private Klassenfelder mit Hash# Präfix definiert:

class MyClass {

  x = 1;
  y = 2;
  static z = 3;

}

console.log( MyClass.z ); // 3
Nach dem Login kopieren
Bitte beachten Sie, dass private Methoden, Getter oder Setter nicht definiert werden können. TC39 Phase 3: Entwurfsvorschlag empfiehlt die Verwendung eines Hash# -Präfixs für Namen, der in Babel implementiert ist. Zum Beispiel:

class MyClass {

  constructor() {
    this.x = 1;
    this.y = 2;
  }

}

MyClass.z = 3;

console.log( MyClass.z ); // 3
Nach dem Login kopieren

Sofort profitieren: besserer React -Code!

reag -Komponenten haben normalerweise Methoden, die an DOM -Ereignisse gebunden sind. Um sicherzustellen, dass dies eine Komponente auflöst, müssen jede Methode entsprechend binden. Zum Beispiel:

class Animal {

  constructor(name = 'anonymous', legs = 4, noise = 'nothing') {

    this.type = 'animal';
    this.name = name;
    this.legs = legs;
    this.noise = noise;

  }

  set eats(food) {
    this.food = food;
  }

  get dinner() {
    return `${this.name} eats ${this.food || 'nothing'} for dinner.`;
  }

}

let rex = new Animal('Rex', 4, 'woof');
rex.eats = 'anything';      // 标准setter
rex.food = 'tofu';          // 完全绕过eats setter
console.log( rex.dinner );  // Rex eats tofu for dinner.
Nach dem Login kopieren
Wenn INCCOUNT als ES2019 -Klassenfeld definiert ist, kann es als Funktion unter Verwendung des ES6 = & GT zugewiesen werden, der automatisch an das Definitionsobjekt gebunden ist. Keine Bindungsanweisung hinzufügen:

class MyClass {

  a = 1;          // .a是公共的
  #b = 2;         // .#b是私有的
  static #c = 3;  // .#c是私有的和静态的

  incB() {
    this.#b++;
  }

}

let m = new MyClass();

m.incB(); // 运行正常
m.#b = 0; // 错误 - 私有属性不能在类外部修改
Nach dem Login kopieren

Klassenfeld: Verbessert?

Die Definition der ES6 -Klasse ist zu einfach. ES2019-Klassenfelder erfordern weniger Code, verbessern die Lesbarkeit und implementieren einige interessante Möglichkeiten für objektorientierte Programmierung. Die Verwendung von # bedeutet, dass Privatsphäre Kritik erhalten hat, vor allem, weil es hässlich ist und sich wie eine Fähigkeit anfühlt. Die meisten Sprachen implementieren das private Schlüsselwort. Der Versuch, dieses Mitglied außerhalb der Klasse zu verwenden, wird vom Compiler abgelehnt. JavaScript wird interpretiert. Betrachten Sie den folgenden Code:

class Animal {

  constructor(name = 'anonymous', legs = 4, noise = 'nothing') {

    this.type = 'animal';
    this.name = name;
    this.legs = legs;
    this.noise = noise;

  }

  speak() {
    console.log(`${this.name} says "${this.noise}"`);
  }

  walk() {
    console.log(`${this.name} walks on ${this.legs} legs`);
  }

}
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Dies wird einen Laufzeitfehler in die letzte Zeile werfen, aber es ist nur eine ernsthafte Folge des Versuchs, die Eigenschaft festzulegen. JavaScript ist absichtlich tolerant, und ES5 ermöglicht die Änderung von Eigenschaften in jedem Objekt. Obwohl ungeschickt, ist das # Symbol außerhalb der Klassendefinition ungültig. Der Versuch, auf MyObject zuzugreifen.#Secret kann einen Syntaxfehler werfen. Diese Debatte wird fortgesetzt, aber Klassenfelder werden bereits in mehreren JavaScript -Motoren wie oder nicht übernommen. Sie werden weiterhin existieren.

FAQs (FAQs) über JavaScript private Klassenfelder

Was sind die Vorteile der Verwendung von Feldern für private Klassen von JavaScript?

private Klassenfelder in JavaScript bieten eine Möglichkeit, Daten in einer Klasse zu verkörpern oder auszublenden, nämlich das Grundprinzip der objektorientierten Programmierung. Diese Einkapselung stellt sicher, dass der interne Zustand eines Objekts nur durch eine explizit definierte Klasse geändert werden kann. Dies macht den Code robuster und vorhersehbarer, da er verhindert, dass externer Code den Zustand des Objekts versehentlich auf unerwartete Weise geändert hat. Darüber hinaus können private Felder dazu beitragen, die Schnittstelle der Klassen zu vereinfachen, da sie die Anzahl der Eigenschaften und Methoden reduzieren, die der Außenwelt ausgesetzt sind.

Wie deklariere ich private Klassenfelder in JavaScript?

In JavaScript werden private Klassenfelder vor dem Feldname ein Hash (#) -Symbol hinzugefügt. Um beispielsweise ein privates Feld mit dem Namen "Wert" in einer Klasse zu deklarieren, können Sie einen #Value schreiben. Dieses Feld kann dann nur in den inneren Methoden der Klasse zugegriffen werden, nicht von außerhalb der Klasse.

Kann ich von außerhalb der Klasse auf private Klassenfelder zugreifen?

Nein, private Klassenfelder in JavaScript können nicht von außerhalb der Klasse zugegriffen werden. Dies geschieht im Entwurf, da eine der Hauptnutzungen privater Felder darin besteht, interne Daten aus der Außenwelt zu verbergen. Wenn Sie versuchen, von außerhalb der Klasse auf ein privates Feld zugreifen zu können, werfen JavaScript einen Syntaxfehler.

Kann ich private Klassenfelder mit öffentlichen Feldern verwenden?

Ja, JavaScript -Klassen können sowohl private als auch öffentliche Bereiche haben. Öffentliche Bereiche werden genauso deklariert wie private Felder, haben jedoch kein Hash (#) -Prefix. Im Gegensatz zu privaten Feldern, auf die nur aus einer Klasse zugegriffen werden kann, können auf öffentliche Felder zugegriffen und von innen und außerhalb der Klasse geändert werden.

Wie unterscheiden sich private Klassenfelder von privaten Methoden in JavaScript?

private Klassenfelder und private Methoden in JavaScript haben ähnliche Verwendungszwecke, die beide eine Möglichkeit bieten, interne Details einer Klasse aus der Außenwelt auszublenden. Sie werden jedoch unterschiedlich verwendet. Private Felder werden verwendet, um Daten zu speichern, auf die nur innerhalb der Klasse zugegriffen werden können, während private Methoden Funktionen sind, die nur innerhalb der Klasse aufgerufen werden können.

Kann ich private Klassenfelder in allen JavaScript -Umgebungen verwenden?

private Klassenfelder sind relativ neue Funktionen in JavaScript, sodass nicht alle Umgebungen dies unterstützen. Zum Zeitpunkt des Schreibens unterstützen die neuesten Versionen der meisten großen Browser, darunter Chrome, Firefox und Safari, private Felder. Internet Explorer unterstützt sie jedoch nicht. Wenn Sie Code schreiben müssen, der in allen Browsern ausgeführt wird, müssen Sie möglicherweise einen Konverter wie Babel verwenden, um den Code in ein Formular umzuwandeln, das ältere Browser verstehen können.

Wie kann ich private Klassenfelder in inneren Methoden einer Klasse verwenden?

Um ein privates Klassenfeld in einer internen Methode einer Klasse zu verwenden, beziehen Sie sich einfach auf das Feld mit seinem Namen (vorangestellt mit einem Hash (#) -Symbol). Wenn Sie beispielsweise ein privates Feld namens "Wert" haben, können Sie in Ihrer Methode wie folgt darauf zugreifen:#Wert.

Kann ich private Klassenfelder in Unterklassen verwenden?

Ja, private Klassenfelder können in Unterklassen von JavaScript verwendet werden. Jede Unterklasse hat jedoch eine eigene unabhängige Gruppe von privaten Feldern, die nicht mit Superklassen oder anderen Unterklassen geteilt werden. Dies bedeutet, dass, wenn das von der Unterklasse deklarierte private Feld mit dem gleichen Namen wie das private Feld in der Superklasse ist, die beiden Felder völlig unabhängig sind und sich nicht gegenseitig stören.

Kann ich private Klassenfelder in statischen Methoden verwenden?

Nein, private Klassenfelder in JavaScript können nicht in statischen Methoden verwendet werden. Dies liegt daran, dass statische Methoden mit der Klasse selbst und nicht mit Instanzen der Klasse verbunden sind und private Felder nur in Fällen der Klasse zugänglich sind.

Kann ich in JavaScript über private Klassenfelder iterieren?

Nein, private Klassenfelder in JavaScript sind nicht in der Eigentums -Iteration des Objekts enthalten. Dies geschieht im Entwurf, da eine der Hauptnutzungen privater Felder darin besteht, interne Daten aus der Außenwelt zu verbergen. Wenn Sie über die Eigenschaften des Objekts iterieren müssen, sollten Sie stattdessen ein öffentliches Feld oder eine Methode verwenden.

Diese Antwort behält das ursprüngliche Bildformat und die Platzierung bei und paraphrasiert den Text, während die ursprünglichen Bedeutung beibehalten wird.

Das obige ist der detaillierte Inhalt vonJavascripts neue private Klassenfelder und wie man sie benutzt. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage