Classes – Objekte in neuem Gewand
Genauso wie Javascript Objekte können Javascript Klassen sowohl Eigenschaften (properties) als auch Funktionen / Methoden aufnehmen.
class Cake { constructor (flavor, method, form, eggs) { this.flavor = flavor; this.method = method; this.form = form; this.eggs = eggs; } cakeRecipe() { return `Dieser Kuchen ist wird mit ${this.flavor} und ${this.eggs} Eiern zubereitet, ${this.method} und als ${this.form} serviert.`; } }
Das ist also die Vorlage oder das Template für die Klasse. Und das Erzeugen einer Instanz:
const schoko = new Cake ("Schoko", "gebacken", "Kastenform", 4); console.log (schoko.cakeRecipe());
Dieser Kuchen ist wird mit Schoko und 4 Eiern zubereitet, gebacken und als Kastenform serviert.
Am Rande: Die Ausgabe von ${this.flavor}, ${this.form} und ${this.eggs} hat keinerlei Bezug zu jQuery, sondern ist ein Template Literal, ebenfalls eine Errungenschaft von ES6.
class constructor
Konstruktoren sind Methoden, die ein Objekt erzeugen, wenn eine neue Instanz der Klasse angelegt wird. Der Konstruktor konstruiert als ein Objekt.
Erzeugen wir eine Klasse cake, dann eine Instanz orangenkuchen, und fügen dann der Klasse kcal für die Kilokalorien hinzu. Alle Kinder erben die neue Eigenschaft automatisch – ob sie wollen oder nicht.
constructor ist ein Teil der class-Syntax. Hat die Klasse keinen Constructor, wird er automatisch erzeugt. Dabei kann jede Javascript-Klasse nur einen Constructor haben.
Class Declaration und Class Expression
Klassen können auf zweierlei Wegen definiert werden: class declaration und class expression.
Deklaration
class Cake { constructor (flavor, method, form, eggs) { this.flavor = flavor; this.method = method; this.form = form; this.eggs = eggs; } }
Expression / Ausdruck
var Cake = class { constructor (flavor, method, form, eggs) { this.flavor = flavor; this.method = method; this.form = form; this.eggs = eggs; } }
Üblich ist die Deklaration der Klasse.
Javascript Class muss nach oben
Eine neue Klasse erbt ihre Eigenschaften vom Prototypen mitsamt all seinen Methoden, und wenn sich eine Klasse ändert, erben alle Kinder / Instanzen die Änderungen – selbst dann, wenn eine Instanz der Klasse bereits erzeugt wurde.
Anders als die meisten Deklaration in Javascript werden Klasse nicht nach oben gehoben (hoisted) und müssen darum vor der ersten Benutzung deklariert werden.
extends
Eine weitere Klasse, die um Eigenschaften und Methoden erweitert werden soll, kennzeichnet diese mit dem Schlüsselwort extends. Das stellt sicher, dass die neue Klasse dieselben Eigenschaften wie ihr Prototyp hat und dazu ihre individuellen Eigenschaften und Methoden.
class Cheesecake extends Cake {
constructor (flavor, method, form, eggs, cover, type, cakeRecipe) {
super ( flavor, method, form, eggs, cakeRecipe);
this.cover = cover;
this.type = "Käsekuchen";
}
cakeGarnish () {
return console.log (`Dieser ${this.type} wird als ${this.form} ${this.method} und schmeckt gut mit ${this.cover}`);
}
}
const c = new Cheesecake ("Quark", "kaltgestellt","Tarte",0,"Himbeeren" );
console.log ("***" + c.cakeGarnish());
Dieser Käsekuchen wird als Tarte kaltgestellt und schmeckt gut mit Himbeeren
super verweist dabei auf den Kontext von der übergeordneten Klasse. Die Vererbung (Inheritance), die bei Javascript Objekten der alten Art eine verschlungene Syntax mitbrachte, ist mit Javascript class einfach auf den Punkt gebracht: Eine Super-Klasse erzeugen und erweitern um zusätzliche Eigenschaften.
Statische Methoden
Statische Methoden sind in den Instanzen der Klasse nicht sichtbar und werden vor allem als Hilfsfunktionen innerhalb der Klasse angelegt.
class Cake {
constructor (flavor, method, form, eggs) {
…
}
cakeRecipe() {
return `…`;
}
static eggsTotal (kuchen1, kuchen2) {
const eggs1 = kuchen1.eggs;
const eggs2 = kuchen2.eggs;
return eggs1 + eggs2;
}
}
const schoko = new Cake ("Schoko", "gebacken", "Kastenform", 4);
console.log (schoko.cakeRecipe());
const mohn = new Cake ("Mohn", "kaltgestellt", "Kastenform", 3);
console.log (mohn.cakeRecipe());
Über die Instanzen finden wir nicht heraus, wieviele Eier schoko und mohn zusammen haben, sondern nur über die Klasse Cake selber.
console.log (Cake.eggsTotal (schoko, mohn));
Eier für beide Kuchen 7
In der Console sehen wir die statische Methode erst beim Prototype:
▶Cake {flavor: "Schoko", method: "gebacken", form: "Kastenform", eggs: 4}
flavor: "Schoko"
method: "gebacken"
form: "Kastenform"
eggs: 4
▶__proto__:
constructor: class Cake
arguments: (...)
caller: (...)
length: 4
▶prototype: {constructor: ƒ, cakeRecipe: ƒ}
eggsTotal: ƒ eggsTotal(kuchen1, kuchen2)
Erst unter __proto__ und darunter protptype wird die statische Methode eggsTotal sichtbar.
Javascript Class vs Function
Wie bereits weiter oben erwähnt: Javascript Klassen werden nicht nach oben angehoben – kein hoisting. Sie müssen deklariert werden, bevor sie benutzt werden.
Funktions-Ausdrücke (function expressions) und Funktionen können überschrieben werden, Klassen nicht. Wenn eine niegelnagelneue Funktion ohne spezielle Eigenschaften und Methoden gebraucht wird, bleibt man vorzugsweise bei Funktionen.
Javascript Class ist immer im Strict Mode, auch wenn kein "use strict" an den Anfang des Scripts gesetzt ist. Der Javascript-Strict Mode wurde in ES5 vorgestellt und verbessert die Qualität des Script Codes.
Browser-Support für Javascript Klassen
Während die immergrünen Browser Firefox, Chrome, Safari und Edge ES6-Klassen seit etwa 2016 unterstützen, bleibt IE11 bei class, extends und super außen vor.