Objektorientierung in JavaScript

Datenkapselung und Geheimnisprinzip

JavaScript ermöglicht bei der Definition von Objekten, ähnlich wie in Java durch die Schlüsselworte private und public, Eigenschaften und Methoden entweder als öffentlich oder privat zu deklarieren. Auch in JavaScript wird hierdurch die Verfügbarkeit dieser Eigenschaften aus den verschiedenen Kontexten heraus geregelt.

Private Eigenschaften können nur aus der Konstruktorfunktion, sowie aus objektinternen Methoden heraus gelesen und geschrieben werden. Der Zugriff von außerhalb des Objektes ist nur auf öffentliche Eigenschaften möglich, sie können also aus jedem Kontext heraus, in dem das Objekt verfügbar ist, aufgerufen werden.

Darüber hinaus werden Methoden anhand Ihrer Zugriffsrechte auf objekteigene Eigenschaften unterschieden. Private Methoden haben Zugriff auf alle öffentlichen und privaten Eigenschaften. Gleiches gilt für privilegierte öffentliche Methoden. Nicht-privilegierte öffentliche Methoden können nur auf öffentliche Eigenschaften zugreifen. Im Folgenden wird die Deklaration der verschiedenen Eigenschaften anhand von Beispielen gezeigt.

Öffentliche Eigenschaften

Öffentliche Eigenschaften werden über das Schlüsselwort this in der DOT-Notation im Konstruktor angelegt. Im nachfolgenden Beispiel wird der Konstruktor für eine Person mit den Attributen vorname, nachname und geschlecht angelegt:

function Person() {
  this.vorname = "Hans";
  this.nachname = "Müller";
  this.geschlecht = "männlich";
}

Erzeugt man nun ein Objekt mit diesem Konstruktor kann auf alle Eigenschaften direkt zugegriffen werden.

Private Eigenschaften

Private Eigenschaften, die von außerhalb des Objekts nicht zugreifbar sind, werden in JavaScript mit dem vorangestellten Schlüsselwort var deklariert:

function Person() {
  this.vorname = "Hans";
  this.nachname = "Müller";
  this.geschlecht = "männlich";
  var alter = 30;
}

Wird nun versucht auf die Eigenschaft alter zuzugreifen wird der Wert undefined zurückgeliefert:

neuePerson = new Person();

Darüber hinaus sind diese Eigenschaften auch nicht von öffentlichen Methoden zugreifbar, sondern nur von privaten Methoden.

Private Methoden

Auf private Funktionen kann nur innerhalb des Konstruktors oder aus privilegierten Methoden heraus zugegriffen werden. Sie werden innerhalb des Konstruktors definiert:

function Person() {
  this.vorname = "Hans";
  this.nachname = "Müller";
  this.geschlecht = "männlich";
  var alter = 30;
  function addYear() {
    alter = alter + 1;
  }
}

Der Zugriff auf die private Funktion addYear erzeugt einen Fehler. Die Bearbeitung des Skripts wird beim Aufruf der Funktion abgebrochen.

Um aus privaten Methoden auf öffentliche Eigenschaften eines Objekts zuzugreifen, muss man sich eines Tricks bedienen. Da this immer das umgebene Objekt refernziert und Funktionen in JavaScript auch Objekte sind, kann in der Methode addYear nicht auf das Attribut geschlecht zugegriffen werden. Allerdings ist es möglich eine Referenz von this auf einer privaten Eigenschaft anzulegen. Üblicherweise wird diese self genannt. Im Folgenden ist der Zugriff innerhalb der privaten Methode addYear auf das Attribut geschlecht möglich:

function Person() {
  //Die Referenz auf das umgebende Objekt wird auf
  //einer private Eigenschaft gespeichert
  var self = this;
  this.vorname = "Hans";
  this.nachname = "Müller";
  this.geschlecht = "männlich";
  var alter = 30;
  function addYear() {
    alter = alter + 1;
    //Jetzt ist der Zugriff auf oeffentliche Eigenschaften
    //durch voranstellen von self moeglich
    self.geschlecht = "weiblich";
  }
  this.getAlter = function() {
    addYear();
    return alter;
  }
}

Privilegierte-Öffentliche Methoden

Solche Methoden werden innerhalb des Konstruktors mit einem vorangestellten this deklariert. Daher können sie auch von außerhalb des Objektes aufgerufen werden:

function Person() {
  this.vorname = "Hans";
    this.nachname = "Müller";
    this.geschlecht = "männlich";
    var alter = 30;
    function addYear() {
      alter = alter + 1;
    }
    this.getAlter = function() {
      addYear();
      return alter;
    }
}
//Objekterzeugung
neuePerson = new Person;

Privilegierte Methoden können also auch auf private Eigenschaften zugreifen.

Nichtprivilegierte-Öffentliche Methoden

Nichtprivilegierte-Öffentliche Methoden werden außerhalb des Konstruktors über das Prototyp-Objekt definiert. Diese Methoden haben nur Zugriff auf öffentliche Eigenschaften eines Objekts:

Person.prototype.changeGeschlecht = function() {
  if (this.geschlecht == "männlich") {
    this.geschlecht = "weiblich";
  } else {
    this.geschlecht = "männlich";
  }
}

Die obige Methode wechselt das Geschlecht einer Instanz von Person. Dies ist möglich, da geschlecht eine öffentliche Eigenschaft ist. Der Zugriff auf private Eigenschaften und Methoden ist nicht möglich.

Überschreiben von Methoden und Eigenschaften

In JavaScript ist es jederzeit möglich, Attribute und Methoden einzelner Objekte zu überschreiben. Dies geschieht, indem man dem Objekt unter gleich bleibendem Eigenschafts- oder Methodennamen neue Werte oder Methoden zuordnet.

function Person() {
  this.vorname = "Hans";
  this.nachname = "Müller";
  this.geschlecht = "männlich";
  var alter = 30;
  function addYear() {
    alter = alter + 1;
  }
  this.getAlter = function() {
    addYear();
    return alter;
  }
}
p = new Person;
//Wert einer oeffentlichen Eigenschaft neu setzen
p.vorname = "Klaus";
//Eine private Eigenschaft mit einer oeffentlichen ueberschreiben
p.alter = 50;
//Eine oeffentliche Methode neu definieren
p.getAlter = function() {return alter +10;}

Getter- und Setter-Methoden

In JavaScript besteht die Möglickeit Getter- und Setter-Methoden zu definieren. Dadurch kann das Überschreiben von Attributen umgangen werden. Die Deklaration von öffentlichen Methoden als Getter- und Setter- Methoden ist problematisch, die diese Methoden, wie eben gesehen, jederzeit überschrieben werden können. JavaScript bietet dagegen die Deklaration von Getter- und Setter-Methoden über eine spezielle Syntax. Diese Methoden sind zwar öffentlich, werden aber nicht explizit aufgerufen, sondern vielmehr implit bei normalem Zugriff auf die Variable.

function myObject(val){
  var value = val;
  this.__defineGetter__("value", function(){
    return value;
  });
  this.__defineSetter__("value", function(val){
    value = val;
  });
}

o = new myObject(0);

Das sofortige Auslesen des Wertes von value funktioniert prinzipiell nicht, da die Variable mit var angelegt wurde. Durch die implizite Verwendung der Getter-Methode funktioniert dies jedoch:

Die Zuweisung von Werten auf value erzeugt auch keine öffentliche Eigenschaft, da auch hier implizit die Setter-Methode genutzt wird.

Die Schlüsselattribute __defineGetter__ und __defineSetter__ definieren diese Methoden. Als Parameter erwarten sie zum Einen einen String, der den Namen der jeweiligen Methode angibt. Zum Anderen erwartet sie eine anonyme Funktion, in der beliebige Berechnungen durchgeführt werden können.

[top]