In der objektorientierten Programmierung ist eine Klasse eine erweiterbare Programmcode-Vorlage zum Erstellen von Objekten, die Anfangswerte für Status (Mitgliedsvariablen) und Implementierungen von Verhalten (Mitgliedsfunktionen oder-methoden) bereitstellt.
In der Praxis müssen wir oft viele Objekte der gleichen Art erstellen, wie Benutzer oder Waren oder was auch immer.
Wie wir bereits aus dem Kapitelkonstruktor wissen, kann der Operator „new“, new function
dabei helfen.,
Aber im modernen JavaScript gibt es ein fortgeschritteneres „Klassen“-Konstrukt, das großartige neue Funktionen einführt, die für die objektorientierte Programmierung nützlich sind.
Die Syntax“ class „
Die grundlegende Syntax lautet:
class MyClass { // class methods constructor() { ... } method1() { ... } method2() { ... } method3() { ... } ...}
Verwenden Sie dann new MyClass()
, um ein neues Objekt mit allen aufgeführten Methoden zu erstellen.
Die – Methode wird automatisch vonnew
aufgerufen, damit wir das Objekt dort initialisieren können.,
Zum Beispiel:
class User { constructor(name) { this.name = name; } sayHi() { alert(this.name); }}// Usage:let user = new User("John");user.sayHi();
Wenn new User("John")
aufgerufen wird:
- Ein neues Objekt wird erstellt.
- Die
constructor
wird mit dem angegebenen Argument ausgeführt und weist siethis.name
zu.
…Dann können wir Objektmethoden aufrufen, z. B. user.sayHi()
.
Eine häufige Falle für unerfahrene Entwickler besteht darin, ein Komma zwischen Klassenmethoden zu setzen, was zu einem Syntaxfehler führen würde.,
Die Notation ist hier nicht mit Objektliteralen zu verwechseln. Innerhalb der Klasse sind keine Kommas erforderlich.
Was ist eine Klasse?
Also, was genau ist eine class
? Das ist keine völlig neue Entität auf Sprachebene, wie man denken könnte.
Lassen Sie uns jede Magie enthüllen und sehen, was eine Klasse wirklich ist. Das wird helfen, viele komplexe Aspekte zu verstehen.
In JavaScript ist eine Klasse eine Art Funktion.,
Hier, werfen Sie einen Blick:
class User { constructor(name) { this.name = name; } sayHi() { alert(this.name); }}// proof: User is a functionalert(typeof User); // function
Was Konstrukt wirklich tut, ist:
- Erstellt eine Funktion namens
User
, das wird das Ergebnis der Klassendeklaration. Der Funktionscode stammt aus derconstructor
– Methode (wird leer angenommen, wenn wir keine solche Methode schreiben). - Speichert Klassenmethoden wie
sayHi
inUser.prototype
.,
Nach new User
Objekt erstellt wird, wenn wir seine Methode aufrufen, ist es aus dem Prototyp genommen, wie im Kapitel F. Prototyp beschrieben. Das Objekt hat also Zugriff auf Klassenmethoden.,der class User
Deklaration:
Hier ist der code zum untersuchen es:
Nicht nur ein syntaktischer Zucker
manche Leute sagen, dass class
ein „syntaktischer Zucker“ (syntax, die ist entwickelt, um machen Dinge einfacher zu Lesen, aber nicht vorstellen, nichts neues), weil wir eigentlich erklären, ohne class
keyword-an alle:
Das Ergebnis dieser definition ist etwa die gleiche., Es gibt also tatsächlich Gründe, warum class
als syntaktischer Zucker betrachtet werden kann, um einen Konstruktor zusammen mit seinen Prototypmethoden zu definieren.
Dennoch gibt es wichtige Unterschiede.
-
Zunächst wird eine von
class
erstellte Funktion durch eine spezielle interne Eigenschaft gekennzeichnet]:"classConstructor"
. Es ist also nicht ganz dasselbe wie das manuelle Erstellen.Die Sprache sucht an verschiedenen Stellen nach dieser Eigenschaft., Im Gegensatz zu einer regulären Funktion muss sie beispielsweise mit
new
aufgerufen werden:class User { constructor() {}}alert(typeof User); // functionUser(); // Error: Class constructor User cannot be invoked without 'new'
Außerdem beginnt eine Zeichenfolgendarstellung eines Klassenkonstruktors in den meisten JavaScript-Engines mit der „class…“
class User { constructor() {}}alert(User); // class User { ... }
Es gibt andere Unterschiede, wir werden sie bald sehen.
-
Klassenmethoden sind nicht aufzählbar.,Eine Klassendefinition setzt
enumerable
flag auffalse
für alle Methoden in der"prototype"
.Das ist gut, denn wenn wir
for..in
über ein Objektfor..in
, möchten wir normalerweise keine Klassenmethoden. -
Klassen immer
use strict
.Der gesamte Code innerhalb des Klassenkonstrukts befindet sich automatisch im strikten Modus.
Außerdem class
Syntax bringt viele andere Funktionen, die wir später erkunden werden.,
Klassenausdruck
Genau wie Funktionen können Klassen in einem anderen Ausdruck definiert, übergeben, zurückgegeben, zugewiesen usw. werden.
Hier ist ein Beispiel für einen Klassenausdruck:
let User = class { sayHi() { alert("Hello"); }};
Ähnlich wie benannte Funktionsausdrücke können Klassenausdrücke einen Namen haben.,
Wenn ein Klassenausdruck einen Namen hat, ist er nur innerhalb der Klasse sichtbar:
Wir können sogar Klassen dynamisch „on-demand“ machen, wie folgt:
Getters/setters
Genau wie Literalobjekte können Klassen Getter/Setter, berechnete Eigenschaften usw. enthalten.
Hier ist ein Beispiel für user.name
implementiert mit get/set
:
Technisch funktioniert eine solche Klassendeklaration durch Erstellen von Gettern und Settern in User.prototype
.,
Berechnete Namen
Hier ist ein Beispiel mit einem berechneten Methodennamen in Klammern :
class User { () { alert("Hello"); }}new User().sayHi();
Solche Funktionen sind leicht zu merken, da sie denen von wörtliche Objekte.
Klassenfelder
Klassenfelder sind eine aktuelle Ergänzung der Sprache.
Zuvor hatten unsere Klassen nur Methoden.
„Klassenfelder“ ist eine Syntax, mit der beliebige Eigenschaften hinzugefügt werden können.,
Zum beispiel, lassen sie uns hinzufügen name
eigenschaft zu class User
:
class User { name = "John"; sayHi() { alert(`Hello, ${this.name}!`); }}new User().sayHi(); // Hello, John!
So, wir schreiben nur “ = “ in die erklärung, und das ist es.,
Der wichtige Unterschied von Klassenfeldern besteht darin, dass sie auf einzelne Objekte gesetzt sind, nicht auf User.prototype
:
class User { name = "John";}let user = new User();alert(user.name); // Johnalert(User.prototype.name); // undefined
Wir können Werte auch mit komplexeren Ausdrücken und Funktionsaufrufen zuweisen:
class User { name = prompt("Name, please?", "John");}let user = new User();alert(user.name); // John
Gebundene Methoden mit Klassenfeldern
Wie im Kapitel gezeigt, haben Funktionsbindungsfunktionen in JavaScript eine dynamische this
., Es hängt vom Kontext des Anrufs ab.
Wenn also eine Objektmethode übergeben und in einem anderen Kontext aufgerufen wird, ist this
kein Verweis mehr auf ihr Objekt.
Dieser Code zeigt beispielsweise undefined
:
Das Problem heißt „losing this
„.
Es gibt zwei Ansätze, dies zu beheben, wie im Kapitel Funktionsbindung erläutert:
- Übergeben Sie eine Wrapper-Funktion, z. B.
setTimeout(() => button.click(), 1000)
. - Binden Sie die Methode an ein Objekt, z. B. im Konstruktor.,
, Class-Felder bieten eine weitere, sehr elegante syntax:
Das class-Feld click = () => {...}
entsteht auf einer pro-Objekt-basis, gibt es eine separate Funktion für jedes Button
Objekt, mit this
innen verweisen auf das Objekt. Wir können button.click
überall herumgeben, und der Wert von this
ist immer korrekt.
Das ist besonders nützlich in Browser-Umgebung, für Ereignis-Listener.,
Zusammenfassung
Die grundlegende Klassensyntax sieht folgendermaßen aus:
MyClass
ist technisch eine Funktion (die wir als constructor
), während Methoden, Getter und Setter in MyClass.prototype
geschrieben werden.
In den nächsten Kapiteln erfahren wir mehr über Klassen, einschließlich Vererbung und andere Funktionen.