====== JavaScript - Objekte ======
Das Konzept des objektorientierten Programmierens hat sich wegen seiner Vorteile schon lange durchgesetzt. Es bildet reale und abstrakte Objekte auf Codestrukturen ab, die leichter verständlich sind und zusammengehörende Daten und Funktionen kapseln. Objekte bieten dem Programmierer wiederverwendbaren Code und erlauben eine bessere Lokalisierung von Fehlem. Objektorientiertes Programmieren erfordert jedoch ein gutes Verständnis der zugrunde liegenden Theorie.
Objekte bestehen aus Eigenschaften und Methoden. Die Eigenschaften sind eine Ansammlung von Werten, die das Objekt näher beschreiben. Methoden sind objekteigene Funktionen, welche die Eigenschaften oder andere Werte ändern. In JavaScript sind die folgenden Schritte zur Verwendung von Objekten notwendig:
* Erstellung der Objektdefinition durch eine Konstruktor-Funktion oder einen Objektinitialisierer
* Hinzufügen von Eigenschaften
* Hinzufügen von Methoden
* Erzeugen von Objekten
* Verwenden der Objekte
\\
===== Grundlagen von Objekten =====
==== Erstellen von Objektdefinitionen über eine Konstruktor-Funktion ====
Eine Konstruktor-Funktion enthält in ihrem Anweisungsblock die Definition der Eigenschaften und Methoden eines Objekts. Mithilfe des Konstruktors können dann sogenannte Instanzen, d. h. Abbildungen des Objekts, im Speicher erzeugt werden. Der Name des Objekts ergibt sich aus dem Namen der Konstruktor-Funktion.
function Konstruktorname(Wertl,Wert2, ...)
{
this.Eigenschaftl = Wertl;
this.Eigenschaft2 = Wert2;
}
Eine Instanz des Objekts wird mit new und dem Aufruf der Konstruktor-Funktion erzeugt, die dabei über-gebenen Parameter werden von der Konstruktor-Funktion zur Initialisierung der Eigenschaften verwendet.
var Instanz = new Konstruktorname(Wertl,Wert2, ...);
Zusätzlich können in der Konstruktor-Funktion Methoden zur Bearbeitung des Objekts deklariert werden. Dabei wird der Name der Methode einer meist gleichnamigen JavaScript-Funktion zugeordnet.
==== Erstellen der Objektdefinition über einen Objektinitialisierer ====
Während über eine Konstruktor-Funktion ein konkreter Objektname zur Verfügung steht, kann man mit einem Objektinitialisierer (seit JavaScript 1.2) anonyme Objekte definieren. Dazu wird einer Variablen eine Liste von Eigenschaft-Wert-Paaren, die durch einen Doppelpunkt getrennt sind, in geschweiften Klammern zugewiesen. Mehrere Paare werden durch Kommata getrennt. Man kann mit einem Objektinitialisierer auch Methoden mit entsprechenden Funktionen definieren.
**Beispiel**
Der Objektvariablen ''ObjVar'' werden die Eigenschaften ''Eigenschaft1, Eigenschaft2'' usw. zugewiesen, die bereits mit einem Wert vorbelegt sind.
var ObjVar = {Eigenschaftl:Wertl,
Eigenschaft2:Wert2,
Methodel: new function() {}
};
document.write(ObjVar.Eigenschaftl);
document.write(ObjVar.Methodel);
\\
===== Eigenschaften =====
Eigenschaften eines Objekts können in jeder Instanz unterschiedliche Werte haben. Instanzen sind somit Vertreter eines Objekts. So ist ein Raumschiff mit dem Namen U.S.S. Enterprise ein Vertreter aller Raumschiffe.
Es soll ein einfaches Objekt für Raumschiffe erstellt werden. Begonnen wird mit einer Konstruktor-Funktion, womit die zwei Eigenschaften Name und Modell für alle Instanzen des Objekts festgelegt werden.
function Raumschiff(Schiffsname, Schiffsmodell)
{
this.Name = Schiffsname;
this.Modell = Schiffsmodell;
}
{{:inf:js:js-59-1.jpg?180|}}
Über das Schlüsselwort this beziehen Sie sich innerhalb der Konstruktor-Funktion immer auf das aktuelle Objekt. Die Eigenschaft Name des aktuellen Objekts wird im Beispiel auf den Wert des ersten übergebenen Parameters (Schiffsname) gesetzt, die Eigenschaft Modell auf den Wert des zweiten Parameters (Schiffsmodell).
Mit der Anweisung new können Sie ab sofort Objekte über die Konstruktor-Funktion Raumschiff erzeugen.
var Enterprise = new Raumschiff("U.S.S. Enterprise","NCC-1701"); |
Eine Variable mit Namen Enterprise wird deklariert, new erzeugt ein neues Objekt mit dem Konstruktor Raumschiff und übergibt diesem die zwei Werte U.S.S. Enterprise und NCC-1701. Der definierte Konstruktor erzeugt daraufhin das Objekt im Speicher und belegt die Eigenschaften mit den übergebenen Werten. Er liefert auch eine Referenz auf die Speicherstelle zurück, die in der Variablen Enterprise abgespeichert wird. Von nun an existiert das Raumschiffobjekt im Speicher und kann über den Variablennamen Enterprise angesprochen werden:
document.write(typeof(Enterprise)); //liefert den Typ - object
Um auf die Eigenschaften dieses Objekts zugreifen zu können, wird der Name des Objekts, gefolgt von einem Punkt und dem Namen der Eigenschaft, verwendet. Alternativ können Sie in eckigen Klammern den Namen der Eigenschaft angeben, der in doppelten Anführungszeichen eingeschlossen ist.
Objekt.Eigenschaft;
Objekt["Eigenschaft"];
In JavaScript wird die Punktnotation für den Zugriff auf Objekteigenschaften und -methoden genutzt. Sie wurde bereits in einigen Anwendungen verwendet, ''document.write()'' ist z.B. die Funktion ''write()'' des ''document''-Objekts, die Ausgaben in ein HTML-Dokument durchführen kann.
Beispiel: [[http://elearn.bgamstetten.ac.at/wiki/addons/JS/raumschiff.html|raumschiff.html]]
Es werden die beiden Raumschiffe Enterprise und Voyager erzeugt. Danach wird auf deren Eigenschaften zugegriffen.
Objekte, Eigenschaften und Methoden
Anlegen zweier Objekte vom Typ Raumschiff
Eigenschaften beschreiben Gemeinsamkeiten von Objekten. Die Werte von Eigenschaften (auch Attribute genannt) des Objekts können bei jeder Instanz unterschiedlich sein. Der erste Schritt, ein Objekt zu definieren, besteht darin, im Anweisungsblock der Konstruktor-Funktion die Eigenschaften zu deklarieren und zu initialisieren. Für jede Eigenschaft wird dazu eine eigene Variable angegeben. Die Anweisung zur Deklaration der Eigenschaft beginnt mit dem Schlüsselwort ''this'', gefolgt von einem Punkt und dem Namen der Eigenschaft. Der Eigenschaft wird danach ein Wert zugewiesen, der z. B. über Parameter übergeben werden kann.
Für Eigenschaften gelten die gleichen Regeln wie für Variablen. Sie können alle einfachen Datentypen beinhalten, aber auch Objekte und Funktionen. Der Zugriff erfolgt im Gegensatz zu Variablen außerhalb des Objekts über den Instanz- und den Eigenschaftsnamen. Der Instanzname verweist auf das entsprechende Objekt, der Eigenschaftsname auf die gewünschte Eigenschaft des verwendeten Objekts.
Im übernächsten Beispiel wird dem Objekt Raumschiff die weitere Eigenschaft Kapitaen hinzugefügt. Der Unterschied zu den bisher verwendeten Eigenschaften liegt darin, dass diese Eigenschaft ebenfalls ein Objekt ist. Um einen Kapitän erzeugen zu können, wird daher zuerst ein Objekt benötigt.
function Person(PersonName, PersonVorname)
{
this.Name = PersonName;
this.Vorname = PersonVorname;
}
{{:inf:js:js-61-1.jpg?180|}}
Über die Konstruktor-Funktion ''Person'' können Sie ein Objekt erzeugen, das die Eigenschaften ''Name'' und ''Vorname'' besitzt.
Beispiel: [[http://elearn.bgamstetten.ac.at/wiki/addons/JS/raumschiff_person.html|raumschiff_person.html]]
Objekte, Eigenschaften und Methoden
Die Personen der Raumschiffe
Zu den definierten Eigenschaften lassen sich weitere hinzufügen. Sie könnten z. B. das Objekt ''Person'' um die Eigenschaften ''Geschlecht'' und ''Lebensform'' erweitern.
Nach der Definition des Objekts Person können Sie den jeweiligen Raumschiffen eine Person als Kapitän zuordnen. Dazu wird das Objekt Raumschiff um die Eigenschaft Kapitaen erweitert.
function Raumschiff(Schiffsname,Schiffsmodell,Kapitaen)
{
this.Name = Schiffsname;
this.Modell = Schiffsmodell;
this.Kapitaen = Kapitaen;
}
Die Konstruktor-Funktion ''Raumschiff'' besitzt jetzt eine Eigenschaft ''Kapitaen''. Als Kapitän des Raumschiffs soll eine Person angegeben werden, die aus dem Objekt ''Person'' erzeugt wurde. Beim Aufruf wird als Argument für die Funktion ''Raumschiff()'' die Variable ''Person'' vom Typ ''object'' übergeben.
Damit ist es möglich, den Vornamen des Raumschiffkapitäns über ein Objekt ''Raumschiff'' und dessen Referenz ''Kapitaen'' auf das Objekt ''Person'' und somit deren Eigenschaft ''Vorname'' auszulesen, Z.B. ''Enterprise.Kapitaen.Name''.
Durch dieses Prinzip können Sie Objekte beliebig tief verschachteln. So kann einer Person über die Eigenschaft Adresse z.B. ein Adressobjekt zugewiesen werden. Auf den Aufenthaltsort könnten Sie dann über Enterprise. Kapitaen.Adresse .Ort zugreifen.
Beispiel: [[http://elearn.bgamstetten.ac.at/wiki/addons/JS/raumschiff_kapitaen.html|raumschiff_kapitaen.html]]
Objekte, Eigenschaften und Methoden
Die Kapitäne der Raumschiffe
Das Objekt Raumschiff wird um die Eigenschaft Kapitaen erweitert. Dazu wird ein Person-Objekt definiert, das die Eigenschaften einer Person vereint. Die Eigenschaft Kapitaen ist vom Typ Person. Um auf eine Eigenschaft des Kapitäns eines Raumschiffs außerhalb eines Objekts zuzugreifen, verwenden Sie den Zugriffspfad ''Raumschiff.Kapitaen.Eigenschaft''.
==== Werte überschreiben ====
Die Eigenschaft Kapitaen des Objekts Enterprise verweist auf dasselbe Objekt wie die Variable kirk. Ändern Sie eine Eigenschaft des Objekts über die Variable kirk, ändert sich ebenfalls der Wert der Eigenschaft Kapitaen im Objekt Enterprise. Die beiden folgenden Anweisungen führen dieselbe Operation aus:
kirk.Lebensform = "Nicht-Vulkanier";
Enterprise.Kapitaen.Lebensform = "Nicht-Vulkanier";
==== Dynamisches Hinzufügen und Löschen von Eigenschaften und Methoden ====
Einer Objektinstanz können dynamisch Eigenschaften hinzugefügt oder daraus entfernt werden. Um einer Objektinstanz eine Eigenschaft hinzuzufügen, muss die Eigenschaft durch einen Punkt getrennt hinter dem Namen der Instanz angegeben werden und ihr ein Wert zugewiesen werden. Über den Operator ''delete'' kann man eine Eigenschaft wieder entfernen. Wird nach dem Entfernen auf die Eigenschaft zu gegriffen, wird der Wert ''undefined'' geliefert. Beachte, dass nur Eigenschaften gelöscht können, die nicht über das Schlüsselwort ''var'' definiert wurden.
**Beispiel**
function Kunde(name){
this.name = name;
}
kd = new Kunde("Meier");
kd.vorname = "Frank"; // neue Eigenschaft hinzufügen
...
delete kd.vorname; // die Eigenschaft wieder entfernen
\\
===== Methoden =====
Funktionen, die einem Objekt zugeordnet sind, werden als Methoden bezeichnet. Sie werden einem Objekt wie eine Eigenschaft zugewiesen.
function Methodenname(Wertl, Wert2, ...){
this.Eigenschaftl = irgendeinWert;
}
function Konstruktorname(Wertl, Wert2, ...){
this.Eigenschaftl = Wertl;
this.Eigenschaft2 = Methodenname;
}
Über das Schlüsselwort function wird eine Funktion in JavaScript definiert. Wird der Funktionsname mit dem Schlüsselwort ''this'' zugewiesen, wird die Funktion als Methode des Objekts interpretiert. Innerhalb der Funktion können Sie mit dem Schlüsselwort this auf die Eigenschaften des aktuellen Objekts zugreifen. this enthält immer eine Referenz auf das aktuelle Objekt.
Beispiel: [[http://elearn.bgamstetten.ac.at/wiki/addons/JS/raumschiff_bewegung.html|raumschiff_bewegung.html]]
Nun können wir dem Objekt ''Raumschiff'' jetzt eine Methode hinzufügen, die eine Fortbewegung des Raumschiffs erlaubt. In dem Beispiel wurde das Objekt ''Person'' zugunsten der Übersicht weggelassen. Deshalb muss auch die Eigenschaft ''Raumschiff.Kapitaen'' entfernt werden.
Objekte, Eigenschaften und Methoden
Und es bewegt sich doch
\\
===== Anweisungen und Operatoren für Objekte =====
==== if-Anweisung ====
Über die ''if''-Anweisung können wir prüfen, ob ein Objekt eine bestimmte Eigenschaft besitzt.
Das Objekt Kunde wird mit der Eigenschaft name definiert. In den beiden folgenden if-Anweisungen wird geprüft, ob ein Objekt Kunde die Eigenschaften name und vorname besitzt.
function Kunde(name){
this.Name = name;
}
var kd = new Kunde('Meier');
if(kd.Name)
document.write("Die Eigenschaft 'Name' im Objekt 'Kunde' existiert.");
if (!kd.Vorname)
document.write("Die Eigenschaft 'Vorname' im Objekt 'Kunde' existiert nicht.");
Wir haben jedoch keine Möglichkeit zu prüfen, ob ein Objekt mit einem bestimmten Namen existiert, d.h., ob eine Konstruktor-Funktion mit diesem Namen vorhanden ist.
\\
==== with-Anweisung ====
Müssen wir hintereinander auf mehrere Eigenschaften und Methoden eines Objekts zugreifen, können wir den Zugriff darauf über die with-Anweisung verkürzen. Dazu wird nach dem Schlüsselwort with der Name der Objektinstanz in Klammern angefügt. Dadurch muss im folgenden Anweisungsblock nur der Name der Eigenschaft ohne den Objektnamen angegeben werden. Dabei wird für jeden Bezeichner zuerst nach einer Eigenschaft im Objekt gesucht, dann nach einem lokalen und globalen Bezeichner.
**Beispiel**
Durch die Verwendung der with-Anweisung müssen Sie innerhalb der geschweiften Klammern in den Methoden ''document.write()'' nicht mehr den Objektnamen kd angeben.
function Kunde(name,vorname){
this.Name = name;
this.Vorname = vorname;
}
var kd = new Kunde("Meier", "Hans");
with(kd) {
document.write("Der Vorname lautet: " + Vorname + "
");
document.write("Der Nachname lautet: " + Name + "
");
)
\\
==== for-in-Anweisung ====
Um über alle Eigenschaften eines Objekts zu iterieren, nutzen Sie diese Anweisung. Dazu wird nach der f or-Anweisung in Klammern eine Laufvariable definiert. Dieser folgen das Schlüsselwort in und ein Objektname oder der Name einer Objektinstanz.
**Beispiel**
Die Laufvariable enthält in jedem Durchlauf den Namen der nächsten Eigenschaft. Außerdem können Sie über den Objektnamen und die gleichzeitige Angabe des Eigenschaftsnamens in eckigen Klammern auf den Wert der Eigenschaft zugreifen. Die folgende Anweisung gibt die Namen der Eigenschaften des Objekts Kunden und dessen Vorgabewerte aus. Sie können diese Anweisung auch für eine Instanz des Objekts Kunden, z.B. kd, ausführen.
function Kunde(name,vorname,alter,geschlecht)
{
this.Name = name;
this.Vorname = vorname;
this.Alter = alter;
this.Geschlecht = geschlecht;
}
var kd = new Kunde('Meier','Hans',65,'männlich');
for(laufvariable in kd)
document.write("Name: " + laufvariable + ", Wert: " + kd[laufvariable]);
\\
==== in-Operator ====
Dieser Operator steht seit JavaScript 1.4 zur Verfügung und kann aus diesem Grund im Internet Explorer zurzeit nicht genutzt werden. Es wird bei dessen Verwendung jedoch keine Fehlermeldung erzeugt. Der ''in''-Operator überprüft, ob eine Eigenschaft in einem Objekt definiert ist. Der Name der Eigenschaft wird dazu in doppelte Anführungszeichen gesetzt. Ist die Eigenschaft vorhanden, wird ''true'' geliefert, sonst ''false''.
**Beispiel**
function Kunde(name,vorname,alter,geschlecht)
{
this.Name = name;
this.Vorname = vorname;
this.Alter = alter;
this.Geschlecht = geschlecht;
}
var kd = new Kunde('Meier','Hans',65,'männlich');
if("Name" in kd)
document.write("Das Objekt 'Kunde' besitzt eine Eigenschaft 'Name'");
\\
==== instanceof-Operator ====
Über diesen Operator können Sie prüfen, ob eine Objektinstanz vom Typ eines bestimmten Objekts ist. In diesem Fall wird als Ergebniswert true geliefert.
**Beispiel**
function Kunde () {}
var kd = new Kunde();
if(kd instanceof Kunde)
document.write("kd ist eine Instanz vom Objekt 'Kunde'");
\\
\\
Beispiel: [[http://elearn.bgamstetten.ac.at/wiki/addons/JS/anweisung+operator.html|anweisung+operator.html]]
Anweisungen und Operatoren für Objekte
Kontrolle, ob Eigenschaften existieren
Ausgabe der Eigenschaften mit "with"
Objekteigenschaften auslesen mit "for... in..."
Objekteigenschaften suchen mit "in"
Objektinstanz kontrollieren mit "instanceof"