Objektorientierung in JavaScript

Objektorientierung (OO) in JavaScript ist eines der meist umstrittenen Themen im Bereich JavaScript. Ursache für diesen Konflikt sind die differierende Umsetzung der OO in JavaScript verglichen mit anderen Programmiersprachen und die Anzahl der verschiedenen Möglichkeiten OO in JavaScript umzusetzen. In diesem Beitrag wird keine endgültige Lösung für diesen Konflikt geliefert, sondern lediglich eine der vielen Möglichkeiten aufgezeigt, wie OO in JavaScript realisiert werden kann.

Klassen werden in JavaScript über Funktionen erzeugt, wobei die Funktion selbst der Konstruktor ist, der bei der Initialisierung eines neuen Objekts ausgeführt wird. Ein wichtiger Aspekt der OO ist die Kapselung. Das heißt, dass die Instanz einer Klasse nicht alle Informationen nach außen gibt, also die Möglichkeit besteht, private und öffentliche Attribute und Methoden zu definieren. Im Nachfolgenden wird anhand der Klasse Person gezeigt, wie die Kapselung von Attributen und Methoden realisiert werden kann.

function Person(firstname, lastname, someAge) {
	// Öffentliche Attribute
	this.firstname = firstname;
	this.lastname = lastname;
   
	// Nur innerhalb der Klasse aufrufbar  
	var isAgeValid = function(someAge) {  
		return someAge > 0;
	}
   
	// Nur innerhalb der Klasse sichtbar
	var age = isAgeValid(someAge) ? someAge : 0;
   
	// Öffentliche Methode
	this.getAge = function() {
		// Innerhalb von öffentlichen Methoden kann auf private
                // Variablen zugegriffen werden
		return age;
	}  
	
	// Öffentliche Methode, die private Methode verwendet
	this.setAge = function(newAge) {
		if (! isAgeValid(newAge)) {
			console.log(newAge, "ist kein valides Alter."); 
		} else {  
			// Anpassen der privaten Variablen
			age = newAge;  
		}  
	}
	
	this.greet = function() {
		console.log("Hallo!");
	}
	
	console.log("Eine Person wurde initialisiert");
}

Nachdem die eigentliche Klasse definiert ist, kann nun eine Instanz der Klasse erzeugt und verwendet werden:

var hans = new Person("Hans", "Maulwurf", 80); // "Eine Person wurde initialisiert"
console.log(hans.firstname); // "Hans"
console.log(hans.getAge()); // 80
hans.setAge(-10); // "-10 ist kein valides Alter."
hans.setAge(69);
console.log(hans.getAge()) // 69

Neben der Kapselung ist die Vererbung ein enorm wichtiger Aspekt der Objektorientierung. Mit dem nachfolgenden Code erbt die Klasse Politician alle öffentlichen Attribute und Methoden der Klasse Person. Geerbte Methoden können überschrieben werden, indem die erbende Klasse eine neue Implementierung für die Methode liefert.

function Politician() {
	// arguments beinhaltet die übergebenen Parameter
	Person.apply(this, arguments);
	
	var party = "";
	
	this.setParty = function(newParty) {
		party = newParty;
	}
	
	this.getParty = function() {
		return party;
	}
	
	// Diese Methode überschreibt die greet Methode aus der Klasse Person
	this.greet = function() {
		console.log("Wählen Sie ", this.lastname, "!");
	}
}

Jetzt kann ein Politician erzeugt und verwendet werden:

var quimby = new Politician("Joe", "Quimby", 10); // "Eine Person wurde initialisiert"
quimby.setParty("Demokratische Partei");
console.log(quimby.getParty()); // "Demokratische Partei"
quimby.setAge(40);
console.log(quimby.getAge()); // 40
quimby.greet(); // "Wählen Sie Quimby!"

Besteht der Bedarf, abstrakte Methoden zu definieren, die von jeder erbenden Klasse überschrieben werden sollen, muss die Methode in der Superklasse so implementiert werden, dass diese beim Aufruf einen Fehler wirft. Nur wenn die erbende Klasse diese Implementierung überschreibt, kann der Code fehlerfrei ausgeführt werden.

function Person() {	
	this.greet = function() {
		throw "Diese Methode muss überschrieben werden.";
	}
}

Fazit

Diese Methode ist einfach zu realisieren und ähnelt stark der Objektorientierung in anderen Programmiersprachen, besitzt allerdings einige Einschränkungen. Eine Einschränkung ist, dass keine geschützten (protected) Attribute und Methoden umgesetzt werden können. Es wird lediglich die Unterscheidung zwischen privaten und öffentlichen Attributen oder Methoden unterstützt. Die zweite Einschränkung betrifft die Polymorphie. Ein Politician ist keine Instanz vom Typ Person:

console.log(quimby instanceof Politician); // true
console.log(quimby instanceof Person); // false

Ist Ihnen Polymorphie enorm wichtig, aber die Kapselung zwischen privaten und öffentlichen Attributen und Methoden nicht, dann könnte die Umsetzung von OO mit Prototyping interessant für Sie sein. Falls auch dieser Ansatz nicht Ihren Vorstellungen entspricht, finden Sie hier einen ausführlichen Vortrag von Douglas Crockford, einem der führenden JavaScript Entwickler. Crockford nennt im Laufe des Vortrags viele weitere Möglichkeiten, um OO in JavaScript umzusetzen und zeigt deren Vor- und Nachteile auf.

Vertiefende Quellen

Introduction to Object-Oriented JavaScript
OOP in JavaScript – What you need to know
Prototyping in JavaScript
Douglas Crockford: Advanced JavaScript

Short URL for this post: http://wp.me/p4nxik-2Aq
This entry was posted in Web as a Platform and tagged , . Bookmark the permalink.

Leave a Reply