born83.com frontend development

Klassen in JavaScript

JavaScript war schon immer eine objektorientierte Programmiersprache. Im Gegensatz zu beispielsweise Java ist JavaScript aber nicht klassenbasiert, sondern basiert auf Prototypen (Object.prototype). An diesem Konzept hat sich auch durch die Einführung von ECMAScript 6 nichts geändert. Allerdings wurde die Syntax erweitert, so dass sich Klassen einfacher erzeugen lassen und die Lesbarkeit des Codes wesentlich verbessert wird.

Konstruktion einer Klasse in JavaScript mit Prototypen

Vor der Erweiterung der Syntax konnte eine Klasse in JavaScript beispielsweise wie folgt erzeugt werden:

var Dog = (function() {
    function Dog(name) {
        this.name = name;
    }
    Dog.prototype.bark = function() {
        console.log(this.name + " barks");
    }
    return Dog;
})();

Hier dient die Funktion function Dog(Name) {...}als Konstruktor. Beim erzeugen eines Objekts der Klasse Dog werden mit Hilfe des Konstruktors die Properties gesetzt. In diesem Fall wird lediglich die übergebene Property name gesetzt, es könnten beliebige weitere Properties gesetzt werden, auch solche, die nicht übergeben wurden.

Die Methode bark() wird an die sogenannte Prototype Chain gebunden. Was genau diese ist und wie sie funktioniert, dazu später mehr.

Dieser Konstruktor kann dann wie eine Klasse verwendet werden:

var snoopy = new Dog("Snoopy");
snoopy.bark();

var lassie = new Dog("Lassie");
lassie.bark();

Erzeugte Objekte einer mit mit Prototypen generierten Klasse

Wenn wir die erzeugten Objekte mit einem console.log("snoopy", snoopy); inspizieren, sehen wir, wie sie aufgebaut sind:

snoopy Dog {name: "Snoopy"}
    name: "Snoopy"
    __proto__: 
        bark: ƒ ()
        constructor: ƒ Dog(name)

Dem Objekt wurde die Property name mit dem Wert “Snoopy” zugewiesen. Außerdem wurde die Funktion bark() zur Prototype Chain hinzugefügt. Beim Aufruf der Funktion wird nun zuerst beim instanziierten Objekt nach einer Implementierung der Funktion gesucht. Hier also zunächst unter snoopy.prototype. Findet sich hier keine Implementierung der Methode, wird auf der nächst höheren Ebene weiter nach einer Implementierung gesucht. In unserem Falle also auf der Ebene des Konstruktors Dog Dog.prototype. Zuletzt wird in JavaScript immer auf der höchsten Ebene gesucht, unter Object.prototype.

Konstruktion einer Klasse in JavaScript mit dem Keyword class

Wie bereits erwähnt ist es dank ECMAScript 6 nun möglich, Klassen wesentlich einfacher zu erzeugen. Das oben verwendete Beispiel der Klasse Dog würde wie folgt aussehen:

class Dog {
    constructor(name) {
        this.name = name;
    }
    bark() {
        console.log(this.name + " barks");
    }
}

Diese Syntax erinnert schon sehr an eine klassenbasierte Objektorientierung und dürfte gerade Java Programmierern bekannt vorkommen. Im Vergleich zur Konstruktion einer Klasse mit Prototypen fällt auf, dass a) für den Konstruktor das Schlüsselwort constructor() verwendet wird und b) die Funktion bark() nun direkt an die Prototype Chain gebunden werden können.

constructor() die Funktion wird bei der Erzeugung eines neuen Objektes aufgerufen. Die Funktion ist also exakt die selbe wie die Funktion des Konstruktors bei Klassen mit Prototypen.

bark() obwohl nicht explizit angegeben, wird die Funktion an die Prototype Chain gebunden und steht später bei den instanziierten Objekten zur Verfügung.

Achtung: anhand der Syntax könnte man vermuten, dass es sich bei der Klasse um ein Objekt-Literal handelt und könnte demnach die Properties mit Komma abtrennen. Dem ist nicht so!

Erzeugte Objekte einer mit dem Keyword class generierten Klasse

Inspizieren wir nun erneut die erzeugten Objekte mit einem console.log("snoopy", snoopy);, sehen wir, dass sie sehr ähnlich aufgebaut sind:

snoopy Dog {name: "Snoopy"}
    name: "Snoopy"
    __proto__: 
        bark: ƒ ()
        constructor: class Dog(name)

Auch hier wurde dem Objekt die Property name mit dem Wert “Snoopy” zugewiesen und die Funktion bark() zur Prototype Chain hinzugefügt. Die Verwendung des Keywords class führt also im Endeffekt zum selben Objekt als Ergebnis wie die bisherige Konstruktion mit Prototypen.

Browser-Unterstützung der JavaScript Klassen

Die gängigen Browser unterstützen die class Syntax in der Regel alle seit spätestens 2016.

Chrome: seit Version 49 Firefox: seit Version 45 Edge: seit Version 12 Safari: seit Version 9 Opera: seit Version 36

Die einzige Ausnahme bildet der Android Chrome Browser - also die mobile Version. Hier wird die Syntax erst seit Mai 2017 und der Version 67 unterstützt.


Mehr zu Klassen unter ECMAScript 6

Wer mehr über Klassen in ECMAScript 6 lesen möchte, findet hier weitere Informationen:

https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Klassen

https://www.ecma-international.org/ecma-262/6.0/#sec-class-definitions

https://caniuse.com/#search=ES6%20classes