7. JavaScript - Objekte

7.1. Definition
7.2. Attribute
7.3. Funktionen
7.4. Vereinfachung (with)
7.5. Objekte in Objekten
7.5. Felder (Arrays, Vektoren)
7.7. for-in-Schleife
7.8. vordefinierte Objekte
7.9. Anfrage nach der Existenz eines Objekts
7.10. Unterschied zu "normalen" Variablen

7.1. Definition

Als Voraussetzung für das Erzeugen eines Objektes ist immer eine Funktion nötig, die dieses Objekt anlegt. Diese Funktion muß der Programmierer selbst schreiben. Diese Funktion darf allerdings nicht normal aufgerufen werden, sondern bekommt das Schlüsselwort new vorgesetzt. Innerhalb der erzeugenden Funktion wird auf die Attribute des zu erzeugenden Objekts mittels this. gefolgt vom Attributnamen zugegriffen.
function Vector3D(x,y,z)
{
  this.x=x;
  this.y=y;
  this.z=z;
}

var vectorA=new Vector3D(7.2, 4.3, 5.4);

Hier wird ein Objekt erzeugt, welches eine Koordinate im dreidimensionalen Raum darstellt. In der erzeugenden Funktion Vector3D wird das Objekt mit den Attributen x, y und z definiert. Durch das Wort new wird das Objekt angelegt und mittels Zuweisung an die Variable vectorA übergeben.

7.2. Attribute

Auf die Attribute des so erzeugten Objekts läßt sich prima in der Form Variablenname.Attribut zugreifen, wie man es auch in C, Java und Pascal tut.
vectorA.x=13.4;
a=vectorA.y;
vectorA.z=vectorA.x+vectorA.y;

Dieses zugegebenermaßen etwas sinnlose Beispiel versteht sich als Fortsetzung dessen des letzten Abschnitts. Es sollte mit Vorkenntnis der bisherigen Kapitel problemlos verständlich sein.

7.3. Funktionen

Das wesentliche an Objekten ist aber die Fähigkeit, Funktionen zu enthalten. Objektzugehörige Funktionen werden separat definiert und in der objekterzeugenden Funktion in das Objekt eingefügt.
Auf diese Art klärt sich auch die Frage der Vererbung:
Verschiedene Objekttypen können durch einfache Zuweisung gleiche Funktionen benutzen.
function Vector3D_len()
{
  return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z);
}

function Vector3D_add(vectorX)
{
  this.x+=vectorX.x;
  this.y+=vectorX.y;
  this.z+=vectorX.z;
}

function Vector3D_subtract(vectorX)
{
  this.x-=vectorX.x;
  this.y-=vectorX.y;
  this.z-=vectorX.z;
}

function Vector3D(x,y,z)
{
  this.x=x;
  this.y=y;
  this.z=z;
  this.len=Vector3D_len;
  this.add=Vector3D_add;
  this.subtract=Vector3D_subtract;
}

function Vector3D_copy(vectorX)
{
  this.Vector3D=Vector3D;
  this.Vector3D(vectorX.x,vectorX.y,vectorX.z);
}

var vectorA=new Vector3D(7.2, 4.3, 5.4);
var vectorB=new Vector3D(4.2, 26.4, 56.2);
var vectorC=new Vector3D_copy(vectorA);
vectorC.add(vectorB);
var a=vectorC.len();

Hier werden drei Funktionen definiert. Vector3D_len errechnet die die Länge eines Vektors und gibt sie zurück,
Vector3D_add addiert einen Vektor zu dem eigenen Vektorobjekt hinzu
und Vector3D_subtract subtrahiert einen Vektor von dem eigenen Vektorobjekt.
Diese drei Funktionen werden von der erzeugenden Funktion unter den Attributnamen len, add und subtract in das Objekt eingefügt.
Zusätzlich zur der objekterzeugenden Funktion Vector3D wird eine weitere objekterzeugende deklariert, sie heißt Vector3D_copy und kopiert einen bereits bestehenden Vektor unter Benutzung der Funktion Vector3D.

Man beachte auch die Benutzung des bereits standardmäßig in JavaScript vordefinierten Objekts Math und seiner Funktion Math.sqrt in der ersten selbstdefinierten Funktion.

Den Gebrauch dieser Funktionalität zeigen die letzten fünf Zeilen. Nachdem die beiden Koordinaten vectorA und vectorB erzeugt wurden, wird vectorC als Kopie von vectorA erzeugt. Danach wird vectorB zu vectorC hinzuaddiert. Anschließend wird die Länge des so veränderten vectorC ermittelt und an die Variable a übergeben.

7.4. Vereinfachung (with)

Um sich den Ausdruck this als Bezug auf das aktuelle Element sparen zu können, kann man explizit mittels with festlegen, daß sich sämtliche Variablennamen des eingeschlossenen Blocks auf die Attribute eines Objekts beziehen. Allerdings verdecken dann die Attributnamen des jeweiligen Objekts eventuell vorhandene globale Variablen gleichen Namens.

Das gleiche Beispiel nochmal mit with:
function Vector3D_len()
{
  with (this)
  {
    return Math.sqrt(x*x+y*y+z*z);
  }
}

function Vector3D_add(vectorX)
{
  with (this)
  {
    x+=vectorX.x;
    y+=vectorX.y;
    z+=vectorX.z;
  }
}

function Vector3D_subtract(vectorX)
{
  with (this)
  {
    x-=vectorX.x;
    y-=vectorX.y;
    z-=vectorX.z;
  }
}

function Vector3D(x,y,z)
{
  this.x=x;
  this.y=y;
  this.z=z;
  this.len=Vector3D_len;
  this.add=Vector3D_add;
  this.subtract=Vector3D_subtract;
}

function Vector3D_copy(vectorX)
{
  this.Vector3D=Vector3D;
  this.Vector3D(vectorX.x,vectorX.y,vectorX.z);
}

var vectorA=new Vector3D(7.2, 4.3, 5.4);
var vectorB=new Vector3D(4.2, 26.4, 56.2);
var vectorC=new Vector3D_copy(vectorA);
vectorC.add(vectorB);
var a=vectorC.len();

Die zur Erzeugung des Objekts benutzten Funktionen dürfen freilich diese Vereinfachung nicht benutzen.

7.5. Objekte in Objekten

Da Objekte im Prinzip nichts weiter sind als gewöhnliche Variablen, kann man sie auch den Attributen anderer Objekte zuweisen.
Folgendes Beispiel setzt das aus dem vorigen Abschnitt fort:
function ThreeAngle_len()
{
  var AB=new Vector3D_copy(this.B);
  AB.subtract(this.A);
  var BC=new Vector3D_copy(this.C);
  BC.subtract(this.B);
  var CA=new Vector3D_copy(this.A);
  CA.subtract(this.C);
  return AB.len()+BC.len()+CA.len();
}

function ThreeAngle(vectorA,vectorB,vectorC)
{
  this.A=vectorA;
  this.B=vectorB;
  this.C=vectorC;
  this.len=ThreeAngle_len;
}

var A=new Vector3D(7.2, 4.3, 5.4);
var B=new Vector3D(4.2, 26.4, 56.2);
var C=new Vector3D(-3.4, -2.7, 0.0);
var threeangle=new ThreeAngle(A,B,C);
var l=threeangle.len();

Dieses Beispiel erzeugt ein Dreieck-Objekt mit den Eckpunkten A, B und C. Über die im vorigen Beispiel definierten Vektoroperationen wird die Länge des Umfanges des Dreiecks berechnet.

7.6. Felder (Arrays, Vektoren)

Arrays kann man als eine Art vordefinierter Objekte betrachten. Der Hauptsinn besteht in der Repräsentation von Zahlenfolgen. Auch Aufzählungen beliebiger anderer Typen und Objekte, sogar in gemischter Form, sind möglich.
var a=new Array(2.3, 4.5, 7.2, 3.3);
var numbers=new Array("first","second","third","fourth","fifth");
var V=new Array(new Vector3D(1,1,1), new Vector3D(2,1,0), new Vector3D(2,1,0));
var c=new Array();
var i;
var text="";

for (i=0;i<10;i++)
  c[i]=i*i*i;

for (i=0;i<4;i++)
  text=text+a[i]+" ";

var threeangle=new ThreeAngle(V[0],V[1],V[2]);

Wie man sieht, lassen sich Array-Elemente über ihre Nummer ansprechen, indem diese in eckigen Klammern [ ] hinter dem Variablennamen angeführt wird.
Die Funktion Array(Element0, Element1, Element2, ...) erzeugt ein neues Feld-Objekt mit den angegebenen Inhalten.
Die Numerierung der Elemente beginnt immer mit 0!

Array-Objekte enthalten auch von sich aus Funktionen, siehe dazu Anhang A - Array -Objekte.

7.7. for-in-Schleife

Mittels der Schlüsselwörter for und in läßt sich für jedes Attribut eines Objekts eine Aktion ausführen.
Die Erklärung soll nur anhand eines Beispieles dargelegt werden:
function TextAttributes(ObjName,Object)
{
  var Result="Attributes of the object \""+ObjName+"\" :\n\n";
  var Attribute;
  for (Attribute in Object)
  {
    Result=Result+ObjName+"."+String(Attribute)+"\n";
  }
  return Result;
}

Diese Beispielfunktion erzeugt einen Text, in dem sämtliche Attribute eines Objekts aufgelistet werden.

Im folgenden Textfeld werden sämtliche Attribute des vordefinierten Objekts window aufgeführt, die der anzeigende Browser unterstützt:


Das sollte im Konqueror3+, Netscape4, Netscape6+, Mozilla und MSIE5+ funktionieren.

7.8. vordefinierte Objekte

Um überhaupt eine HTML-Seite manipulieren zu können, müssen vordefinierte Objekte zur Kommunikation mit dem Browser vorhanden sein. Solche standardmäßig zu JavaScript gehörende Objekte heißen beispielsweise window, document (welches auch ein Unterobjekt von window ist), Math und so weiter.

Eine Auflistung samt Erklärungen befindet sich im Anhang A.

7.9. Anfrage nach der Existenz eines Objekts

Mit einer einfachen Fallunterscheidung der Form if (Objektname) läßt sich das Vorhandensein eines Objekts überprüfen.

Beispielsweise existiert das Objekt "window.document.all" nur im Microsoft-Modell, dem allerdings auch KDE-Konqueror und Opera folgen. Der Navigator kennt das Objekt in den bisherigen Versionen noch nicht.
function CheckAll()
{
  if (window.document.all)
    return "Microsoft model with \"window.document.all\"";
  else
    return "Netscape model without \"window.document.all\"";
}




7.10. Unterschied zu "normalen" Variablen

var a=3.75;
var b=a;
a=4.76;

Wie erwartet, behält die Variable b bei der letzten Zuweisung der Variablen a ihren zuvor von b zugewiesenen Wert 3.75;

var a=new Vector3D(7.2, 4.3, 5.4);
var b=a;
a.x=3.4;

In diesem Fall nimmt mit der letzten Zuweisung auch b.x den Wert 3.4 an.
Dies beruht auf der Tatsache, daß mit der Zuweisung von Objekten nur Referenzen gesetzt werden, Objekte werden also nicht kopiert.
In unserem Beispiel verweisen die Referenzen a und b auf dasselbe Objekt.
Eine Veränderung des Objekts über die Referenz a spiegelt sich auch über die Referenz b wieder.

Bezogen auf die im Abschnitt 7.3 definierten Funktionen läßt sich dieses Verhalten durch vollständige Kopie eines Objekts umgehen:
var a=new Vector3D(7.2, 4.3, 5.4);
var b=new Vector3D_copy(a);
a.x=3.4;


Autor: Ulrich Kritzner