XT Knowledge Base
Hauptseite | Über | Hilfe | FAQ | Spezialseiten | Anmelden

Druckversion | Impressum | Datenschutz | Aktuelle Version

OOP mit JavaScript

Version vom 22:16, 7. Sep. 2010 bei Monettenom (Diskussion | Beiträge)

Inhaltsverzeichnis

Einleitung

Dieses Tutorial basiert auf einen Artikel von Gavin Kistner und dessen Korrektur durch Shelby H. Moore III.

Deklaration von Klassen

Folgende Klasse repräsentiert einen Punkt im zweidimensionalen Raum.

function Point2D( x, y )
{
  this.x = x ? x : 0;
  this.y = y ? y : 0;
}
Der Ausdruck
<argument> ? <argument> : 0;
sorgt dafür, dass die Variablen auch dann richtig initalisiert werden, wenn keine Argumente übergeben werden. (Default-Konstruktor).

Eine JavaScript-Klasse sieht aus wie eine gewöhnliche Funktion. Diese Funktion übernimmt aber gleichzeitig die Aufgabe einer Klassen-Deklaration und die eines Konstruktors.

Die Erzeugung einer Instanz und der Zugriff darauf geschieht wie folgt:

  var p = new Point2D( 10, 15 );
  alert( "x: " + p.x + ", y: " + p.y ); // x: 10, y: 15

Im Vergleich zur Deklaration erscheint die Instanziierung dann aber eher so, wie man es erwarten würde.

Methoden

Insgesamt werden drei Möglichkeiten genannt, einer Klasse Methoden hinzuzufügen:

Zuweisung von Funktionen im Konstruktor

function Point2D( x, y )
{
  this.x = 0;
  this.y = 0;

  this.set = function( x, y )
  {
    this.x = x;
    this.y = y;
  }

  this.set( x ? x : 0, y ? y : 0 );
}

In diesem Fall wird im Konstruktor eine set()-Methode gesetzt und direkt aufgerufen. Letztendlich ist das nichts anderes als die Initialisierung einer Funktionsvariablen.

Diese Funktion ist nun auch "von außen" aufrufbar:

  var p = new Point2D( 1, 3 );
  p.set( 3, 1 );
  alert( "x: " + p.x + ", y: " + p.y ); // x: 3, y: 1

Deklaration von Methoden über "prototype"

Eine etwas übersichtlichere und empfohlene Möglichkeit ist die nachträgliche Zuweisung von Methoden:

function Point2D( x, y )
{
  this.x = 0; 
  this.y = 0;         
  this.set( x, y );
}

Point2D.prototype.set = function( x, y )
{
  this.x = x ? x : 0;
  this.y = y ? y : 0;
}

var p2 = new Point2D;
p2.set( 30, 21 );

In diesem Beispiel wird eine function "set" dem prototype der Point2D-Klasse hinzugefügt und kann auch im Konstruktor aufgerufen werden. Tatsächlich scheint es keinen Unterschied zu machen, welche Methode gewählt wird.

Private Member und Methoden

Ein verbreiteter Irrtum ist, dass es möglich ist, private Methoden zu deklarieren:

function Point2D( x, y )
{
  this.x = 0; 
  this.y = 0;

  function set( x, y )
  {
    this.x = x ? x : 0;
    thix.y = y ? y : 0;
  }

  this.set( x, y );
}

Das funktioniert definitiv nicht, da this innerhalb der Funktion set auf window verweist. this ist nicht verfügbar, also wäre das eine ganz normale lokale Funktion, deren Sichtbarkeit sich auf den Konstruktor beschränkt. Diese Methoden sind als weder Methoden, noch sind sie privat.

Ebenso gibt es keine privaten Member. Es ist möglich, innerhalb des Konstruktors lokale Variablen anzulegen. Deren Sichtbarkeit ist aber ebenso nur auf den Konstruktor selbst beschränkt.

Vererbung

Mit JavaScript ist es möglich, alle Methoden und Attribute einer Klasse an den prototype einer anderen Klasse zu übergeben:

Point3D.prototype = new Point2D();

Ohne weiteres Zutun hat man nun zweite Klasse, die eine exakte Kopie der ersten darstellt. Nun kann der prototype der zweiten Klasse beliebig verändert werden, ohne Auswirkungen auf die erste Klasse zu haben:

function Point2D( x, y )
{
  this.x = 0; 
  this.y = 0;         
  this.set( x, y );
}

Point2D.prototype.set = function( x, y )
{
  this.x = x ? x : 0;
  this.y = y ? y : 0;
}

Point3D.prototype = new Point2D();

function Point3D( x, y, z )
{
  this.z = z ? z : 0;
  this.set( x, y );
}

var p = new Point3D( 1, 2, 3 );
alert( "x: " + p.x + ", y: " + p.y + ", z: " + p.z ); // x: 1, y: 2, z: 3

Natürlich könnte nun Point3D eine eigene set()-Methode anbieten, die x, y und z als Parameter erhält:

Point3D.prototype.set = function( x, y, z )
{
  this.x = x ? x : 0;
  this.y = y ? y : 0;
  this.z = z ? z : 0;  
}

Konstruktoren

Schöner wäre es allerdings, wenn man den Konstruktor der Klasse aufrufen könnte, dessen Member und Methoden man geerbt hat.

Das ist tatsächlich einfach zu realisieren:

Point3D.prototype.set = function( x, y, z )
{
  Point2D.call( this, x, y );
  this.z = z ? z : 0;  
}

Hier wird diel call()-Methode von Funktions-Objekten aufgerufen und ein Zeiger auf this samt Parameterliste übergeben. this zeigt nun auf ein Point3D-Objekt und wird dem Point2D-Konstruktor untergeschoben. Dieser initialisiert nun den Teil, der an die Point3D-Klasse vererbt wurde.

Virtuelle Methoden


Finden

Blättern
Hauptseite
XT Knowledge Base-Portal
Aktuelle Ereignisse
Letzte Änderungen
Zufällige Seite
Konfiguration
Hilfe
Ändern
Quelltext betrachten
Bearbeitungshilfe
Seitenoptionen
Diskussion
Neuer Abschnitt
Druckversion
Seitendaten
Versionen
Links auf diese Seite
Änderungen an verlinkten Seiten
Meine Seiten
Anmelden
Spezialseiten
Neue Seiten
Dateiliste
Statistik
Mehr …