Kurz: Mit Klassen (ES2015) beschreibst du Bauanleitungen für Objekte. Unter der Haube nutzt JavaScript weiterhin Prototypen, aber die Klassensyntax ist deutlich lesbarer.
Teil des Kurses JavaScript
Kapitel 21 von 40 im Kurs JavaScript (Abschnitt „Objektorientierung“). Mit Fortschritt, Quiz und Zertifikat auf der Lernseite.
Mit Klassen (ES2015) beschreibst du Bauanleitungen für Objekte. Unter der Haube nutzt JavaScript weiterhin Prototypen, aber die Klassensyntax ist deutlich lesbarer.
Klasse definieren
class Hund {
constructor(name, alter) {
this.name = name;
this.alter = alter;
}
bellen() {
return `${this.name} sagt: Wuff!`;
}
get menschenJahre() {
return this.alter * 7;
}
}
const rex = new Hund("Rex", 3);
console.log(rex.bellen(), rex.menschenJahre);
console.log(rex instanceof Hund, typeof Hund);Ausgabe:
Rex sagt: Wuff! 21
true functionconstructorläuft beinew Hund(...)und setzt die Anfangswertethisist das neue Objekt- Methoden stehen direkt in der Klasse, ohne
function getmacht aus einer Methode eine berechnete Eigenschaft
Statische Member und private Felder
class Konto {
#stand = 0; // privates Feld (nur in der Klasse sichtbar)
static anzahl = 0; // gehört zur Klasse, nicht zum Objekt
constructor(inhaber) {
this.inhaber = inhaber;
Konto.anzahl++;
}
einzahlen(betrag) {
if (betrag <= 0) throw new RangeError("Betrag muss positiv sein");
this.#stand += betrag;
return this;
}
get stand() { return this.#stand; }
static vergleiche(a, b) { return a.#stand - b.#stand; }
}
const k = new Konto("Mia").einzahlen(100).einzahlen(50);
console.log(k.stand, Konto.anzahl);
console.log(Konto.vergleiche(k, new Konto("Tom")));Ausgabe:
150 1
150Der Zugriff k.#stand von außen ist sogar ein Syntaxfehler, schon beim Laden des Programms:
Fehlermeldung:
SyntaxError: Private field '#stand' must be declared in an enclosing classEchte Privatheit gibt es also mit #. Ein vorangestellter Unterstrich (_stand) ist nur eine Konvention.
Vererbung
class Tier {
constructor(name) { this.name = name; }
laut() { return "..."; }
vorstellen() { return `${this.name} macht ${this.laut()}`; }
}
class Katze extends Tier {
laut() { return "Miau"; }
}
class Hund extends Tier {
constructor(name, rasse) {
super(name); // Konstruktor der Oberklasse
this.rasse = rasse;
}
laut() { return "Wuff"; }
vorstellen() { return super.vorstellen() + ` (${this.rasse})`; }
}
for (const t of [new Katze("Mimi"), new Hund("Rex", "Schäfer"), new Tier("?")]) {
console.log(t.vorstellen());
}
console.log(new Hund("a", "b") instanceof Tier);Ausgabe:
Mimi macht Miau
Rex macht Wuff (Schäfer)
? macht ...
trueIn einer Unterklasse muss super() aufgerufen werden, bevor du this benutzt.
Prototypen unter der Haube
Jedes Objekt hat einen Verweis auf einen Prototyp, in dem JavaScript nach nicht gefundenen Eigenschaften weitersucht (Prototypenkette):
class A { hallo() { return "A"; } }
class B extends A {}
const b = new B();
console.log(Object.getPrototypeOf(b) === B.prototype);
console.log(Object.getPrototypeOf(B.prototype) === A.prototype);
console.log(b.hallo === A.prototype.hallo, b.hasOwnProperty("hallo"));Ausgabe:
true
true
true falseMixins und Komposition
JavaScript erlaubt nur eine Oberklasse. Zusätzliche Fähigkeiten fügst du als Funktion hinzu:
const KannSchwimmen = Basis => class extends Basis {
schwimmen() { return `${this.name} schwimmt`; }
};
class Tier { constructor(n) { this.name = n; } }
class Ente extends KannSchwimmen(Tier) {}
console.log(new Ente("Donald").schwimmen());Ausgabe:
Donald schwimmtthis und Methoden als Callback
class Zaehler {
stand = 0;
erhoehen = () => { this.stand++; }; // Arrow-Feld: this bleibt gebunden
falsch() { this.stand++; }
}
const z = new Zaehler();
const f = z.erhoehen, g = z.falsch;
f(); f();
try { g(); } catch (e) { console.log("falsch:", e.name); }
console.log(z.stand);Ausgabe:
falsch: TypeError
2Merke
classmitconstructor, Methoden,get/setundstatic- Private Felder mit
#name extendsundsuperfür Vererbung- Hinter den Klassen steckt die Prototypenkette
- Methoden als Callback verlieren
this: mit Arrow-Feld oderbindlösen
Übungsaufgabe
Baue eine Klasse Rechteck mit breite und hoehe, einer Methode flaeche() und einer Unterklasse Quadrat.
Quiz zur Selbstkontrolle
Wann wird constructor aufgerufen?
- Bei new Klasse(…) (richtig)
- Beim Import
- Beim Löschen
- Bei jeder Methode
Wie kennzeichnest du ein privates Feld?
- #name (richtig)
- private name
- _name (echte Privatheit)
- $name
Was muss in einer Unterklasse vor this aufgerufen werden?
- super() (richtig)
- new()
- parent()
- init()
Weiter im Kurs
Zurück: Reguläre Ausdrücke
Weiter: Fehlerbehandlung
Alle Kapitel: JavaScript im Überblick