Objektorientiertes Javascript

In der heutigen Zeit kommt man selten drum herum massiv Javascript verwenden zu müssen. Benutzeroberflächen werden auf modernen Seiten immer intuitiver und dynamischer. Da bleibt es nicht aus, dass das dahinterliegende Javascript sehr komplex wird. In einem meiner aktuellen Projekte ist dies der Fall. Grob beschrieben geht es dabei um die Validierung von Benutzereingaben. Für das Vergleichsrechner Framework, welches aktuell noch für fast jeden Vergleichsrechner auf vergleichen-und-sparen.de und wohl zukünftig auch für Vergleichsrechner auf safe.me eingesetzt wird, habe ich ein objektorientiertes Validator System entwickelt. Da stellte sich mir zwangsläufig die Frage, ob man dies nicht auch auf Basis von Javascript entwickeln könne?

Wie Javascript objektorientiert funktionieren kann, möchte ich hier kurz an einem kleinen Beispiel erläutern. Es wird grundlegendes Know How im Umgang mit objektorientierten Begrifflichkeiten vorausgesetzt.

Namespaces

Um Konflikte mit eventuell schon vorhandenen Javascript Objekten vorzubeugen, empfiehlt es sich Namespaces einzusetzen. Ja, das geht glücklicherweise auch mit Javascript. Anders als in PHP ist ein Namespace in Javascript auch nur ein Objekt, welches Eigenschaften, Methoden und weitere Objekte umfasst.

// globaler namespace
var MMNEWMEDIA = MMNEWMEDIA || {};

// Beispiel eines Objekts mit Namespace
MMNEWMEDIA.meinObjekt = {
    meineEigenschaft : '',
    meineMethode : function( parameter1, parameter2 ) {
        // macht hier irgendwas
    }
};

Im Grunde genommen setzen wir den Namespace als einfaches Objekt und prüfen hierbei gleich, ob dieses Objekt bereits besteht. Dies kann nützlich sein, wenn man seine Definitionen auf mehrere Dateien aufteilt.

Objekte und Eigenschaften

Wie andere Programmiersprachen auch, kennt Javascript ebenfalls Objekte, Methoden und Eigenschaften. Wie unter den Namespaces schon kurz angedeutet, gestalten sich diese Objekte recht einfach. Hierzu ein kurzes, einfaches Beispiel.

MMNEWMEDIA.Fahrzeug = function( farbe, leistung ) {
    this.farbe = farbe || 'schwarz', // Farbe des Fahrzeugs mit Standard Wert "schwarz"
    this.leistung = leistung || 0, // Leistung des Fahrzeuges in PS mit Standard Wert 0
};

var Fahrzeug = new MMNEWMEDIA.Fahrzeug( 'blau', 150 );
alert(Fahrzeug.farbe); // gibt "blau" aus

Javascript ist eine auf Prototypen basierte Sprache. Aus diesem Grund gibt es, anders als in anderen Programmiersprachen, hier auch kein class Statement. Javascript nutzt statt dessen Funktionen als Klassen. Das hat mich am Anfang auch ziemlich verwirrt. Man gewöhnt sich aber recht schnell dran. Klassen zu definieren ist also genau so einfach, wie Funktionen in Javascript zu definieren. Im Beispiel haben wir eine Fahrzeug Klasse definiert, welche die beiden Eigenschaften Farbe und Leistung enthält. Eigenschaften werden innerhalb von Objekten mit dem Statement this angesprochen.

Methoden

Methoden innerhalb eines Objektes folgen eigentlich der gleichen Logik von Eigenschaften innerhalb eines Objekts. Methoden werden einer Eigenschaft als Funktion zugeordnet, welche mehrere Argumente entgegen nehmen kann. Der feine Unterschied zu anderen Programmiersprachen ist hier das Prototyping. Javascript ist, wie bereits erwähnt, keine klassenbasierte Programmiersprache. Man verfolgt hier einen anderen Weg der objektorientierten Programmierung. Die Prototype basierte Programmierung. Jedes Objekt funktioniert hier als Prototyp. Dazu folgendes Beispiel.

MMNEWMEDIA.Fahrzeug.prototype.fahre = function( richtung, geschwindigkeit ) {
    alert( 'Das ' + this.farbe + ' Fahrzeug fährt mit ' + geschwindigkeit + ' km/h ' + richtung + '.' );
}

var Fahrzeug = new MMNEWMEDIA.Fahrzeug( 'blau', 150 );
Fahrzeug.fahre( 'geradeaus', 100 ); // Gibt "Das blaue Fahrzeug fährt mit 100 km/h geradeaus" aus

Wir benutzen hier sowohl die übergebenen Funktionsparameter als aus die Eigenschaften des Fahrzeug Objektes, um daraus einen Satz zu bilden.

Vererbung

Vererbung ist eigentlich nichts anderes, als das Prinzip einer übergeordneten Klasse, welche als Basis für viele andere, davon abgeleiteter, spezialisierter Klassen dienen kann. Man spricht in diesem Sinne von Eltern- und Kindklassen. Dazu folgendes Beispiel basierend auf unserer Fahrzeug Klasse.

// Definition der Klasse Rennauto
MMNEWMEDIA.Rennauto = function( farbe, leistung, team ) {
    MMNEWMEDIA.Fahrzeug.call( this, farbe, leistung );
    this.team = team;
}

// Rennauto Prototype Objekt über Vererbung des Fahrzeug Objektes
MMNEWMEDIA.Rennauto.prototype = Object.create( MMNEWMEDIA.Fahrzeug );

// Den Konstruktor zurücksetzen auf das Rennauto Objekt
MMNEWMEDIA.Rennauto.prototype.constructor = MMNEWMEDIA.Rennauto;

// Die fahre Methode des Fahrzeug objektes überschreiben
MMNEWMEDIA.Rennauto.prototype.fahre = function( richtung, geschwindigkeit ) {
    alert( 'Das ' + this.farbe + ' Rennauto des Teams ' + this.team + ' rast mit ' + geschwindigkeit + ' km/h ' + richtung + '.' );
}

// Eine tanken Methode hinzufügen
MMNEWMEDIA.Rennauto.prototype.tanken = function() {
    alert( 'Das ' + this.farbe + ' Rennauto des Teams ' + this.team + ' fährt zum tanken in die Boxengasse.' );
}

// Aufruf
var rennauto = new MMNEWMEDIA.Rennauto( 'rot', 800, 'Scuderia Ferrari' );
rennauto.fahre( 'geradeaus', 260 ); // Das rote Rennauto des Teams Scuderia Ferrari rast mit 260 km/h geraus
rennauto.tanken(); // Das rote Rennauto des Temas Scuderia Ferrari fährt zum tanken in die Boxengasse

Im gezeigten Beispiel leiten wir die Rennauto Klasse von der Fahrzeug Klasse ab. Das Rennauto hat natürlich ein Team, welches als Eigenschaft für das Rennauto festgelegt wird. Im Beispiel wird die fahre Methode des Fahrzeug Objektes überschrieben und es wurde eine tanken Methode hinzugefügt. Die Rennauto Klasse kann auf die Eigenschaften der Fahrzeug Klasse zurückgreifen.

Hier machen sich für mich aber auch die Nachteile des Prototypings bemerkbar. Der Konstruktor der abgeleiteten Klasse muss nach der eigentlichen Vererbung wieder zurückgesetzt werden. Das erscheint mir ein bisschen unkomfortabel, ist aber wohl nicht zu ändern. Jetzt, wo klar ist, wie OOP mit Javascript funktioniert, kann ich auch das Eingangs erwähnte Validieren von User Eingaben wie im Vergleichsrechner Framework aufbauen.

Anmerkungen

Die hier gezeigten Beispiele dienen lediglich als einfache Veranschaulichung wesentlicher Eigenschaften von Javascript in Bezug auf die Objektorientierte Programmierung. Es ist darauf zu achten, dass Funktionen, wie z.b. Object.create() nicht in allen Browsern zur Verfügung stehen können. Grundsätzlich ist also bei Javascript immer auf die Eigenheiten der jeweiligen Browser zu achten, da es sich hier um eine Client seitige Programmiersprache handelt.

1 Gedanke zu „Objektorientiertes Javascript“

  1. Hallo Marcel,

    danke für den guten Beitrag, zur Zeit versuche ich alles zu dem Thema aufzusaugen, da die Bücher die ich für mein Fernstudium im Bereich OOP bekommen habe eher trocken und schwer zu lesen sind. Daher bin ich immer wieder froh über solche Seiten wie deine.

    Viele Grüße

    Antworten

Kommentar verfassen

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.