Javascript Class – Klassen

Javascript Object Prototype

Javascript Class kam mit ES6 an und ummantelt Object Prototyping und Inheritance mit einer einfachen Syntax – charmant als syntaktischer Zuckerguss bezeichnet. Mit den neuen Schlüsselwörtern lehnt sich der Javascript-Prototyp besser an die Objektorientierung der klassischen Programmiersprachen an.

23-02-02 SITEMAP CSS HTML JS Basis JS Web Tutorial SVG

Classes – Objekte in neuem Gewand

Genauso wie Javascript Objekte nehmen Javascript Klassen sowohl Eigenschaften (properties) als auch Funktionen / Methoden auf.

class Cake {
	constructor (flavor, time, deco, eggs) {
		this.flavor = flavor;
		this.time = time;
		this.deco = deco;
		this.eggs = eggs;
	}
	
	cakeRecipe() {
		return `Dieser Cupcake ist wird mit ${this.flavor} und ${this.eggs} Eiern zubereitet, 
		        ${this.time} min gebacken und mit ${this.deco} serviert.`;
	}
}

Das ist also die Vorlage oder das Template für die Klasse. Und das Erzeugen einer Instanz:

const schoko = new Cake ("Schokostreusel", 15, "Sahne", 4);
console.log (schoko.cakeRecipe());

const mohn = new Cake ("Mohn", 10, "Kirschen", 3);
console.log (mohn.cakeRecipe());

const quark = new Cake ("Quark", 20, "Pflaumensoße", 2);
console.log (quark.cakeRecipe());

… und schon haben wir die Rezepte für 3 Cupcakes im Kasten.


Dieser Cupcake ist wird mit Schokostreusel und 4 Eiern zubereitet, 15 min gebacken und mit Sahne serviert.
Dieser Cupcake ist wird mit Mohn und 3 Eiern zubereitet, 10 min gebacken und mit Kirschen serviert.
Dieser Cupcake ist wird mit Quark und 2 Eiern zubereitet, 20 min gebacken und mit Pflaumensoße serviert.

Am Rande: Die Ausgabe von ${this.flavor}, ${this.time} 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 also 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, time, deco, eggs) {
      this.flavor = flavor;
      this.time = time;
      this.deco = deco;
      this.eggs = eggs;
   }
}
Expression / Ausdruck
const Cake = class {
   constructor (flavor, time, cover, eggs) {
      this.flavor = flavor;
      this.time = time;
      this.deco = deco;
      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 Klassen nicht nach oben gehoben (hoisted) und müssen darum vor der ersten Benutzung deklariert bereits sein.

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. Dann können wir jetzt neben kleinen Cupcakes auch Torten backen.

class Torte extends Cake {
	constructor (flavor, time, deco, eggs, cover, type, cakeRecipe) {
		super ( flavor, time, deco, eggs, cakeRecipe);
		this.cover = cover;
		this.type = "Torte";
	}
	
	cakeGarnish () {
		return  `Diese ${this.type} wird ${this.time} min gebacken, 
		         mit Schichten von ${this.deco} aufgebaut und 
		         mit ${this.cover} überzogen`;
	}
}

const c = new Torte ("Mohntorte", 15, "Mohnsahne", 0, "Marzipan" );
console.log ("cakeGarnish" , c.cakeGarnish());
cakeGarnish – "Diese Torte wird 15 min gebacken, mit Schichten von Mohnsahne aufgebaut 
              und mit Marzipan überzogen" 

super verweist dabei auf den Kontext 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, time, cover, 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 ("Eier für beide Kuchen", Cake.eggsTotal (schoko, mohn));
Eier für beide Kuchen 7

In der Console sehen wir die statische Methode erst beim Prototype:

▶Cake {flavor: "Schokostreusel", method: 15, deco: "Kirschsahne", eggs: 4}
   flavor: "Schoko"
   method: 15
   fdeco: "Kirschsahne"
   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.