# Objektorientierung

Objekte in Programmiersprachen sind am einfachsten zu erklären, wenn Sie sich einen bestimmten Gegenstand vor Augen halten. Stellen Sie sich als Objekt einfach ein Auto vor. Sie können über ein Auto verschiedene Aussagen machen, z. B. in welcher Farbe es lackiert wurde, ob es ein 2-, 4- oder 5-Türer ist, wie viel Liter Hubraum und wie viel PS der Motor des Autos besitzt usw. Alles das sind Variablen bzw. Eigenschaften des Autos. Auch eine Interaktion mit dem Auto ist möglich. So lassen sich die Türen des Autos öffnen, die Zündung kann betätigt und die Scheinwerfer können eingeschaltet werden, und natürlich kann das Auto von einer Person gesteuert werden. Alles das sind Funktionen bzw. Methoden des Autos.

Exakt über solche Eigenschaften und Methoden verfügen auch Objekte in der objektorientierten Programmierung (kurz OOP). Eine Eigenschaft eines Objekts ist mit einer Variablen gleichzusetzen und eine Methode mit einer Funktion. Dies bedeutet also, dass ein Objekt die Summe aus Variablen und Funktionen ist. Viele Programmiersprachen bieten schon vorgefertigte Objekte an, die Sie in Ihren eigenen Programmen verwenden können. So wird beispielsweise bei der Anweisung document.write die Methode write des Objekts document aufgerufen. Natürlich verfügt auch document über Eigenschaften, z. B. title. Diese Eigenschaft enthält den Titel des Dokuments, der mit dem title-Element festgelegt wurde, und die Eigenschaft lastModified enthält das letzte Änderungsdatum eines HTML-Dokuments.

Testen Sie einmal das folgende Beispiel in Ihrem Browser:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Objekte //-->
<html>
  <head>
    <title>Listing 4.1</title>
  </head>
  <body>
    <script type="text/javascript">
      <!--
        titel = document.title;
        aenderung = document.lastModified;
        adresse = document.URL;
        hintergrundfarbe = document.bgColor;
        document.write("<h1>Details zu "+titel+"</h1>");
        document.write("<h3>Letzte &Auml;nderung: "+aenderung+"</h3>");
        document.write("<h3>URL: "+adresse+"</h3>");
        document.write("<h3>Hintergrund: "+hintergrundfarbe+"</h3>");
      //-->
    </script>
  </body>
</html>

Listing 4.1: Weitere Eigenschaften des document-Objekts

Das Listing 4.1 gibt im Browser den Dokumenttitel, das Datum und die Uhrzeit der letzten Änderung, die URL bzw. den Pfad des Dokuments und den Wert der Hintergrundfarbe aus.

# Eigenschaften

Wie Sie also eben festgestellt haben, können Sie die Eigenschaften von Objekten problemlos auslesen und einer Variablen mit dem =-Operator zuweisen. Umgekehrt können Sie der Eigenschaft eines Objekts mit dem =-Operator auch einen Wert zuweisen. Dies ist jedoch nicht bei jeder Eigenschaft möglich, denn einige von ihnen sind nur zum Auslesen gedacht. Dazu gehören die Eigenschaften title, URL und lastModified des document-Objekts. Die Eigenschaft bgColor können Sie sowohl auslesen als auch verändern. Das folgende Beispiel soll dies verdeutlichen:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Objekte: Eigenschaften verändern //-->
<html>
  <head>
    <title>Listing 4.2</title>
    <script type="text/javascript">
      <!--
        function aendereFarbe()
        {
          document.bgColor = "#FF0000";
        }
      //-->
    </script>
  </head>
  <body>
    <a href="javascript:aendereFarbe()">Farbe &auml;ndern!</a>
  </body>
</html>

Listing 4.2: Den Wert einer Eigenschaft ändern

Testen Sie das Listing 4.2 in Ihrem Browser. Nachdem Sie auf den Link geklickt haben, wird die Hintergrundfarbe des Dokuments in Rot (\#FF0000) geändert.

Beachten Sie, dass der Hex-Tripel-Wert in Anführungsstrichen steht und somit als String an document.bgColor übergeben worden ist. Achten Sie auch auf die Groß- und Kleinschreibung der Objektnamen, Eigenschaften und Methoden.

Für das Auto-Objekt könnten Sie nun auch verschiedene Eigenschaften festlegen. Gehen Sie einmal davon aus, Sie würden sich für einen VW Polo entscheiden, dann würden Sie das Objekt sicherlich polo oder vwpolo nennen. Als Eigenschaften könnte es farbe, tueren, hubraum und PS erhalten. Diese Eigenschaften können Sie nun mit dem =-Operator auslesen oder schreiben.

polo.farbe = "silber";       // Der Polo wird silber  
polo.tueren = 3;             // Der Polo bekommt 4 Türen  
hubraum = polo.hubraum;      // Wie viel Liter hat der Motor?  
leistung = polo.PS;          // Und wie viel PS?

Um also auf Eigenschaften eines Objekts eine Lese- oder Schreiboperation durchzuführen, wird zuerst der Bezeichner des Objekts und, durch einen Punkt getrennt, die Eigenschaft notiert.

Mit den Vergleichsoperatoren können Sie auch Bedingungen festlegen, z. B. ab wie viel Leistung in PS Sie den Polo kaufen würden:

if(polo.leistung > 75)  
{  
  polo.kaufen();  
}

# Methoden

Methoden sind Funktionen eines Objekts. So ist z. B. write eine Methode des Objekts document. Auch alert oder prompt sind die Methoden eines Objekts, und zwar des Objekts window. Das Besondere an diesem Objekt ist, dass Sie beim Lesen und Schreiben einer Eigenschaft oder beim Ausführen einer Methode dieses Objekt nicht explizit angeben müssen. So könnten Sie anstelle von

alert("Willkommen auf meiner Webseite!");  
eingabe = prompt("Wie ist Ihr Name? ","");

auch

window.alert("Willkommen auf meiner Webseite!");  
eingabe = window.prompt("Wie ist Ihr Name? ","");

schreiben. Eine weitere Methode des Objekts window lautet confirm. Diese Methode fordert den Benutzer auf, entweder mit Ja oder mit Nein zu antworten. Als Ergebnis liefert die Methode dann entweder true, wenn der Benutzer auf OK geklickt hat, oder false, wenn er auf Abbrechen geklickt hat.

ergebnis = window.confirm("Klicken Sie auf OK, wenn Sie Fan von Hertha BSC sind.");  
if(ergebnis == true)  
{  
  alert("Toll, ein Fan von Hertha BSC.");  
}  
else  
{  
  alert("Kein Fan von Hertha? Schade.");  
}

Für das Objekt polo könnten die Methoden oeffneTuer, anlassen, lichtan, lichtaus und fahren lauten. Dabei können die Methoden Parameter erwarten, einen Wert zurückgeben oder beides.

polo.oeffneTuer("Fahrertür");  
laeuftMotor = polo.anlassen();  
if(laeuftMotor == true)  
{  
  polo.lichtan();  
  polo.fahren(50);  
}

Zuerst wird die Methode oeffneTuer ausgeführt. Anschließend wird der Motor angelassen. Die Methode liefert true zurück, wenn der Motor läuft. Ist dies der Fall, werden die Scheinwerfer eingeschaltet, und der Wagen wird auf 50 (km/h) beschleunigt.

# Objekthierarchie

Es ist sehr gut möglich, dass ein Objekt ein weiteres Objekt enthält und Sie aus dem untergeordneten Objekt eine Eigenschaft auslesen oder eine Methode ausführen möchten. Das Objekt document, das Sie bereits kennen gelernt haben, ist ein untergeordnetes Objekt von window. Da Sie das window-Objekt zum Ausführen einer seiner Methoden nicht extra anführen müssen, müssen Sie dies beim document-Objekt auch nicht tun. Es ist aber trotzdem möglich. Das window-Objekt wird dann, ebenfalls getrennt durch einen Punkt, vor dem document-Objekt notiert.

window.document.write("Hallo WWW!");

# Objekte instanziieren

Ein Objekt basiert immer auf einer Klasse, so wie eine Methode auf einer Funktion und eine Eigenschaft auf einer Variablen basiert. JavaScript kennt von vornherein eine Menge verschiedener Klassen. Eine davon ist Date, mit der verschiedene Datums- und Zeitoperationen durchgeführt werden können, wie z. B. die Anzeige des aktuellen Datums. Da Objekte ähnlich funktionieren wie Variablen, muss vor der Verwendung eines Objekts einer Date-Klasse dieses erst einmal erzeugt werden. Man spricht dabei von einer Instanz. Um eine Instanz einer Klasse zu erzeugen (und somit ein Objekt), müssen Sie den =-Operator und das reservierte Wort new (dt. neu) verwenden.

datum = new Date();

Zuerst wird ein Bezeichner für das Objekt notiert, bei dessen Namensgebung die gleichen Regeln wie beim Bezeichnen von Variablen gelten. Anschließend folgen der =-Operator und das Schlüsselwort new. Als Letztes wird die Klasse notiert, auf der das neue Objekt basieren soll. Die runden Klammern nach dem Klassennamen müssen notiert werden – aus welchem Grund, werden Sie später noch erfahren.

Das folgende Beispiel stellt dar, wie man ein Objekt der Klasse Date verwenden muss, um im Browser des Benutzers das aktuelle Datum auszugeben.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Objekte instanziieren //-->
<html>
  <head>
    <title>Listing 4.3</title>
    <script type="text/javascript">
      <!--
        datum = new Date();
        document.write(datum);
      //-->
    </script>
  </head>
  <body>
  </body>
</html>

Listing 4.3: Ausgabe des aktuellen Datums und der Uhrzeit im Browser

Browserausgabe des Listing 4.3 im Internet Explorer 6.0 Abbildung 4.1: Browserausgabe des Listing 4.3 im Internet Explorer 6.0

In Listing 4.4 wird zuerst das Objekt datum erzeugt, das auf der Klasse Date basiert. Anschließend werden mit document.write(datum); das aktuelle Datum und die Uhrzeit im UNIX-Format ausgegeben. Die Ausgabe des Datums und der Uhrzeit im Browser lässt von der Formatierung her zu wünschen übrig. Daher sollten Sie diese Ausgabe ein wenig verfeinern und das Listing 4.3 um einige Zeilen Code erweitern:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Datum und Uhrzeit //-->
<html>
  <head>
    <title>Listing 4.4</title>
    <script type="text/javascript">
      <!--
        datum = new Date();
        std = datum.getHours();
        min = datum.getMinutes();
        sek = datum.getSeconds();
        tag = datum.getDate();
        mon = datum.getMonth() + 1;
        jhr = datum.getYear();
        document.write("<h3>Datum: "+tag+"."+mon+"."+jhr+"</h3>");
        document.write("<h3>Uhrzeit: "+std+":"+min+":"+sek+"</h3>");
      //-->
    </script>
  </head>
  <body>
  </body>
</html>

Listing 4.4: Ausgabe des aktuellen Datums und der Uhrzeit in einer anwenderfreundlicheren Formatierung

Ausgabe des Listing 4.4 im Internet Explorer 6.0 Abbildung 4.2: Ausgabe des Listing 4.4 im Internet Explorer 6.0

Die Methoden getHours(), getMinutes() und getSeconds() des datum-Objekts ermitteln jeweils die Anzahl der vergangenen Stunden, Minuten und Sekunden seit 0:00 Uhr. Die Methode getYear() ermittelt die aktuelle Jahreszahl. Je nach Systemumgebung des Benutzers wird diese Zahl entweder zweistellig oder vierstellig ausgegeben.

Die Methode getMonth() gibt die Zahl des Monats aus. Die Zählung beginnt jedoch mit 0. Der Januar entspricht dabei also der Zahl 0 und der Dezember der Zahl 11. Deshalb wird zu dem durch getMonth() ermittelten Wert 1 hinzuaddiert. Die Methode getDate() liefert den Tag als Zahl zurück. Mit der Anweisung document.write werden anschließend einmal das Datum und einmal die Uhrzeit ausgegeben.

# Mehrere Anweisungen

Wenn Sie wie in Listing 4.4 mehrere Methoden eines Objekts ausführen möchten, kann es sehr umständlich werden, jedes Mal den Namen des Objekts und anschließend die Methode zu notieren. Deshalb wurde mit der Anweisung with (dt. mit) Abhilfe geschaffen. In runden Klammern notieren Sie hinter with ein Objekt, und in geschweiften Klammern folgen dann die Methoden des Objekts.

with([Objekt])  
{  
  [Anweisungsblock]  
}

Die Vereinfachung des Listing 4.4 mit der Anweisung with sieht dann wie folgt aus:

datum = new Date();  
with(datum)  
{  
  std = getHours();  
  min = getMinutes();  
  sek = getSeconds();  
  tag = getDate();  
  mon = getMonth() + 1;  
  jhr = getYear();  
}  
document.write("<h3>Datum: "+tag+"."+mon+"."+jhr+"</h3>");  
document.write("<h3>Uhrzeit: "+std+":"+min+":"+sek+"</h3>");

Sie sollten dabei aber etwas beachten: Wenn Sie einen with-Block um ein längeres Code-Fragment (oder gar um den gesamten Quelltext) setzen, leidet darunter unter Umständen die Lesbarkeit. Sie sollten also möglichst einen Mittelweg finden und with-Blöcke nur dann einsetzen, wenn es hilft, den Quelltext zu lesen.

# Eigene Klassen

Bisher habe ich immer behauptet, dass Objekte Instanzen einer Klasse sind. Dies ist in der objektorientierten Programmierung auch so vorgesehen und festgelegt. Jedoch wurde dies in JavaScript ein wenig schlampig umgesetzt, denn JavaScript ist nicht wirklich objektorientiert, sondern objektangelehnt. Der Unterschied besteht darin, dass Sie immer eine Möglichkeit finden werden, um die Verwendung von Objekten zu umgehen, was in einer objektorientierten Sprache nicht oder nur sehr schwer möglich wäre. Zwar können Sie in JavaScript eigene Klassen erzeugen und davon auch Objekte instanziieren, jedoch lassen sich diese Klassen nicht als solche kennzeichnen. In Java wird eine Klasse beispielsweise mit dem Schlüsselwort class eingeleitet, genau wie in PHP – nicht so in JavaScript. Dort müssen Sie eine Funktion definieren, die andere Funktionen referenziert, und bilden schlussendlich daraus die Klasse. Ich möchte Ihnen aber an dieser Stelle trotzdem die Verwendung von eigenen Klassen in JavaScript kurz erklären.

Fangen Sie mit einer Klasse an, die lediglich zwei Eigenschaften enthält. Diese Klasse soll als Basis für Objekte dienen, die ein Auto repräsentieren. Als Eigenschaften soll diese Klasse die Farbe und die Anzahl der Türen des Autos erhalten.

function automobil()  
{  
  this.farbe = "keine Farbe";  
  this.tueren = "keine Türen";  
}

Zuerst wird also eine normale Funktionsdefinition vorgenommen. Im Anweisungsblock der Funktion wird dann mit dem Schlüsselwort this (dt. dieses) das eigene Objekt referenziert. An dieser Stelle müssen Sie this verwenden, da Sie den Bezeichner des Objekts später frei wählen und somit nicht in der »Klassendefinition« mit angeben können. Daraus folgt, dass sich this immer auf das eigene Objekt bezieht. Nach this folgen einmal farbe und einmal tueren. Damit wird eine Variable für diese Klasse definiert, die später als Eigenschaft des Objekts zur Verfügung steht. Da zu Beginn weder die Farbe noch die Anzahl der Türen des Autos feststehen, bekommen Sie den Wert "keine Angabe" zugewiesen. Mit der Anweisung

polo = new Automobil();

könnten Sie nun ein neues Objekt instanziieren, das auf der Klasse Automobilbasiert. Zu Beginn des Kapitels habe ich auch von Hubraum und Leistung gesprochen. Auch diese Eigenschaften lassen sich dieser Klasse noch hinzufügen.

function automobil()  
{  
  this.farbe = "keine Angabe";  
  this.tueren = "keine Angabe";  
  this.hubraum = "keine Angabe";  
  this.PS = "keine Angabe";  
}

Den Eigenschaften eines Objekts dieser Klasse könnten Sie nun Werte zuweisen, oder Sie könnten Werte auslesen:

polo = new Automobil();  
polo.farbe = "silber";  
polo.tueren = 5;  
polo.hubaum = 1598;  
polo.PS = 75;  
document.write("Farbe: "+polo.farbe);  
document.write("Hubraum: "+polo.hubraum);

Wenn Sie dieses Auto nun kaufen möchten, benötigen Sie noch eine entsprechende Methode. Nennen Sie diese Methode einmal kaufen. Zuerst definieren Sie die Funktion kaufen und weisen sie anschließend der Klasse Automobil als Methode zu.

function kaufen()  
{  
  alert("Sie haben dieses Auto in "+this.farbe+"gekauft.");  
}  
function automobil()  
{  
  this.farbe = "keine Angabe";  
  this.tueren = "keine Angabe";  
  this.hubraum = "keine Angabe";  
  this.PS = "keine Angabe";  
  this.kaufen = kaufen;  
}

Bei der Definition von Methoden für eine Klasse werden die runden Klammern nicht notiert.

this.[Methodenname] = [Funktionsname];

Der Methodenaufruf könnte nun folgendermaßen stattfinden. Zuerst setzen Sie neue Werte für die Eigenschaften des Objekts und führen anschließend die Methode kaufen aus, um das Auto zu erwerben.

polo = new Automobil();  
  // Eigenschaft festlegen  
polo.farbe = "silber";  
polo.tueren = 5;  
polo.hubraum = 1598;  
polo.PS = 75;  
  // Auto kaufen  
polo.kaufen();

# Zusammenfassung

  • Objekte sind eine Menge von Variablen und Funktionen. Variablen bilden die Eigenschaften eines Objekts und Funktionen die Methoden.
  • Objekte basieren auf Klassen. Sie werden durch das Instanziieren einer Klasse erzeugt. Dies erfolgt mit der Anweisung new und dem Zuweisungsoperator =.
  • Objekte können auch andere Objekte enthalten.
  • Der Zugriff auf Eigenschaften, Methoden oder Unterobjekte erfolgt durch die Angabe der Bezeichner, getrennt durch einen Punkt.
  • Bei der Definition einer Klasse kann auf Eigenschaften und Methoden durch das Schlüsselwort this zugegriffen werden.
  • Klassen in JavaScript werden jedoch nicht, wie in anderen Programmiersprachen sonst üblich, mittels class definiert, sondern durch eine Funktion.

# Fragen und Übungen

  1. Programmierer sind schreibfaul. Welche Erleichterungen stehen zur Verfügung, wenn Sie auf verschiedene Eigenschaften und Methoden eines Objekts zugreifen möchten, ohne jedes Mal den Bezeichner des Objekts angeben zu müssen?
  2. Wie nennen sich Variablen eines Objekts?
  3. Wie nennen sich Funktionen eines Objekts?
  4. Wie wird ein neues Objekt instanziiert? Zeigen Sie dies am Beispiel der Klasse Date.