Klassen in JavaScript
Im letzten Artikel haben wir einige grundlegende Konzepte der objektorientierten Programmierung (OOP) eingeführt und ein Beispiel besprochen, bei dem wir OOP-Prinzipien verwendet haben, um Professoren und Studenten in einer Schule zu modellieren.
Wir haben auch darüber gesprochen, wie es möglich ist, Prototypen und Konstruktoren zu verwenden, um ein solches Modell zu implementieren, und dass JavaScript auch Funktionen bietet, die klassischen OOP-Konzepten näher kommen.
In diesem Artikel werden wir diese Funktionen durchgehen. Es ist wichtig zu beachten, dass die hier beschriebenen Funktionen keine neue Art der Kombination von Objekten darstellen: Unter der Haube verwenden sie immer noch Prototypen. Sie sind lediglich eine Möglichkeit, die Einrichtung von Prototypenketten zu erleichtern.
Voraussetzungen: | Grundkenntnisse in HTML und CSS, Vertrautheit mit den Grundlagen von JavaScript (siehe Erste Schritte und Bausteine) und den Grundlagen der objektorientierten Programmierung in JavaScript (siehe Einführung in Objekte, Objektprototypen und Objektorientierte Programmierung). |
---|---|
Ziel: | Zu verstehen, wie man die von JavaScript bereitgestellten Funktionen verwendet, um "klassische" objektorientierte Programme zu implementieren. |
Klassen und Konstruktoren
Sie können eine Klasse mit dem class
-Schlüsselwort deklarieren. Hier ist eine Klassendeklaration für unsere Person
aus dem vorherigen Artikel:
class Person {
name;
constructor(name) {
this.name = name;
}
introduceSelf() {
console.log(`Hi! I'm ${this.name}`);
}
}
Dies deklariert eine Klasse namens Person
, mit:
- einer
name
-Eigenschaft. - einem Konstruktor, der einen
name
-Parameter übernimmt, welcher verwendet wird, um diename
-Eigenschaft des neuen Objekts zu initialisieren - einer Methode
introduceSelf()
, die auf die Eigenschaften des Objekts mitthis
verweisen kann.
Die name;
-Deklaration ist optional: Sie könnten sie weglassen, und die Zeile this.name = name;
im Konstruktor wird die name
-Eigenschaft vor der Initialisierung erstellen. Das explizite Auflisten von Eigenschaften in der Klassendeklaration kann es jedoch für Personen, die Ihren Code lesen, einfacher machen zu sehen, welche Eigenschaften Teil dieser Klasse sind.
Sie könnten die Eigenschaft auch mit einem Standardwert initialisieren, wenn Sie sie deklarieren, mit einer Zeile wie name = '';
.
Der Konstruktor wird mit dem constructor
-Schlüsselwort definiert. Genau wie ein Konstruktor außerhalb einer Klassendefinition wird er:
- ein neues Objekt erstellen
this
an das neue Objekt binden, sodass Sie in Ihrem Konstruktorcode aufthis
verweisen können- den Code im Konstruktor ausführen
- das neue Objekt zurückgeben.
Anhand des obigen Klassendeklarationscodes können Sie eine neue Person
-Instanz wie folgt erstellen und verwenden:
const giles = new Person("Giles");
giles.introduceSelf(); // Hi! I'm Giles
Beachten Sie, dass wir den Konstruktor mit dem Namen der Klasse, Person
in diesem Beispiel, aufrufen.
Konstruktoren auslassen
Wenn Sie keine spezielle Initialisierung benötigen, können Sie den Konstruktor weglassen, und ein Standardkonstruktor wird für Sie generiert:
class Animal {
sleep() {
console.log("zzzzzzz");
}
}
const spot = new Animal();
spot.sleep(); // 'zzzzzzz'
Vererbung
Basierend auf unserer Person
-Klasse oben, definieren wir die Unterklasse Professor
.
class Professor extends Person {
teaches;
constructor(name, teaches) {
super(name);
this.teaches = teaches;
}
introduceSelf() {
console.log(
`My name is ${this.name}, and I will be your ${this.teaches} professor.`,
);
}
grade(paper) {
const grade = Math.floor(Math.random() * (5 - 1) + 1);
console.log(grade);
}
}
Wir verwenden das extends
-Schlüsselwort, um anzugeben, dass diese Klasse von einer anderen Klasse erbt.
Die Professor
-Klasse fügt eine neue Eigenschaft teaches
hinzu, also deklarieren wir das.
Da wir teaches
festlegen möchten, wenn ein neuer Professor
erstellt wird, definieren wir einen Konstruktor, der name
und teaches
als Argumente annimmt. Das Erste, was dieser Konstruktor tut, ist, den Superklassen-Konstruktor mit super()
aufzurufen und dabei den name
-Parameter weiterzugeben. Der Superklassen-Konstruktor kümmert sich um die Festlegung von name
. Danach setzt der Professor
-Konstruktor die teaches
-Eigenschaft.
Hinweis:
Wenn eine Unterklasse eine eigene Initialisierung durchführt, muss sie zuerst den Superklassen-Konstruktor mit super()
aufrufen, um etwaige Parameter weiterzugeben, die der Superklassen-Konstruktor erwartet.
Wir haben auch die Methode introduceSelf()
von der Superklasse überschrieben und eine neue Methode grade()
hinzugefügt, um eine Arbeit zu bewerten (unser Professor ist nicht sehr gut und vergibt zufällige Noten für Arbeiten).
Mit dieser Deklaration können wir jetzt Professoren erstellen und verwenden:
const walsh = new Professor("Walsh", "Psychology");
walsh.introduceSelf(); // 'My name is Walsh, and I will be your Psychology professor'
walsh.grade("my paper"); // some random grade
Kapselung
Schließlich wollen wir untersuchen, wie die Kapselung in JavaScript implementiert werden kann. Im letzten Artikel haben wir besprochen, dass wir die Eigenschaft year
der Student
-Klasse privat machen möchten, damit wir die Regeln für Bogenschießkurse ändern können, ohne dass dabei Code bricht, der die Student
-Klasse verwendet.
Hier ist eine Deklaration der Student
-Klasse, die genau das tut:
class Student extends Person {
#year;
constructor(name, year) {
super(name);
this.#year = year;
}
introduceSelf() {
console.log(`Hi! I'm ${this.name}, and I'm in year ${this.#year}.`);
}
canStudyArchery() {
return this.#year > 1;
}
}
In dieser Klassendeklaration ist #year
eine private Daten-Eigenschaft. Wir können ein Student
-Objekt erstellen und intern #year
verwenden, aber wenn Code außerhalb des Objekts versucht, auf #year
zuzugreifen, gibt der Browser einen Fehler aus:
const summers = new Student("Summers", 2);
summers.introduceSelf(); // Hi! I'm Summers, and I'm in year 2.
summers.canStudyArchery(); // true
summers.#year; // SyntaxError
Hinweis: Im Chrome-Konsolenmodus ausgeführter Code kann auf private Eigenschaften außerhalb der Klasse zugreifen. Dies ist eine nur auf DevTools beschränkte Lockerung der JavaScript-Syntax-Beschränkung.
Private Dateneigenschaften müssen in der Klassendeklaration deklariert werden, und ihre Namen beginnen mit #
.
Private Methoden
Man kann sowohl private Methoden als auch private Dateneigenschaften haben. Genau wie bei privaten Dateneigenschaften beginnen ihre Namen mit #
, und sie können nur von den Methoden des Objekts selbst aufgerufen werden:
class Example {
somePublicMethod() {
this.#somePrivateMethod();
}
#somePrivateMethod() {
console.log("You called me?");
}
}
const myExample = new Example();
myExample.somePublicMethod(); // 'You called me?'
myExample.#somePrivateMethod(); // SyntaxError
Testen Sie Ihr Wissen!
Sie haben das Ende dieses Artikels erreicht, aber können Sie sich an die wichtigsten Informationen erinnern? Es gibt einige weitere Tests, um zu überprüfen, ob Sie diese Informationen behalten haben, bevor Sie weitermachen — siehe Testen Sie Ihr Wissen: Objektorientiertes JavaScript.
Zusammenfassung
In diesem Artikel haben wir die wichtigsten Werkzeuge durchgearbeitet, die JavaScript zur Verfügung stellt, um objektorientierte Programme zu schreiben. Wir haben nicht alles hier abgedeckt, aber das sollte ausreichen, um Ihnen den Einstieg zu erleichtern. Unser Artikel über Klassen ist eine gute Anlaufstelle, um mehr zu erfahren.