Objektorientierung in JavaScript

Closures

Garbage Collection

ECMAScript verwendet eine automatische Garbage Collection. Dabei werden Objekte, die nicht mehr referenziert werden können für den Garbage Collector freigegeben. Diese Objekte werden zu einem späteren Zeitpunkt zerstört und die von ihnen belegten Ressourcen freigegeben.

Was sind Closures?

Eine Closure ist eine spezielle Art von Objekt, welches eine Funktion mit einem Geltungsbereich verbindet. Sie entsteht, wenn eine verschachtelte Funktion auf Variablen aus dem Geltungsbereich ihrer äußeren Funktion zugreift. Die Closure schließt dann alle lokalen Variablen des Geltungsbereiches der äußeren Funktion zum Zeitpunkt der Entstehung der Funktion ein, daher der Name Closure. Dadurch wird verhindert, dass die lokalen Variablen nach Ablauf der Funktion dem Garbage Collector zugänglich gemacht werden. Bedingung dafür ist, dass weiterhin eine Referenz auf die innere Funktion besteht. Somit kann die innere Funktion noch lange nach Ablauf der äußeren Funktion auf deren lokalen Variablen zugreifen, obwohl auf diese keine Referenz mehr existiert.

Closures erstellen

Closures werden erstellt, indem eine Funktion ein Funktionsobjekt als Rückgabewert hat, welches innerhalb dieser Funktion erstellt wurde.

In einem einfachen Beispiel soll zunächst das Grundkonzept von Closures verstanden werden:

function aussen(a) {
  function innen(b,c)
    {
    x = a+b+c;
    return(x);
  }
return(innen); }

Im Beispiel wird eine Closure gebildet, die die lokale Variable a der Funktion aussen konserviert, sodass diese weiterhin in der Funktion innen verfügbar ist. Folgendes ist also möglich:

Und ebenso dieser Aufruf:

x = aussen(2);

Ein zweites Beispiel zeigt wie man öffentliche Funktionen deklariert, die mittels Closures auf private Funktionen und Variablen zugreifen.

//Funktionsdeklaration, sowie direkter Aufruf der Funktion
//Die Funktion agiert als eine Art anonymer Konstruktor
var Counter = (function() {
  var privateCounter = 0;
  //nur diese private Funktion kann die private Variable veraendern
  function changeBy(val) {
    privateCounter += val;
  }
  //Rueckgabe von drei oeffentlichen Funktionen in JSON-Notation
  return {
    increment: function() {
      changeBy(1);
    },
    decrement: function() {
      changeBy(-1);
    },
    value: function() {
      return privateCounter;
    }
  }
})(); //Man beachte die (), sie fuehren die Funktion aus!

Im Beispiel wird eine anonyme Funktion deklariert und direkt ausgeführt, sodass ihre Rückgabewerte in der Variablen Counter gespeichert werden. Die Funktion beinhaltet die private Variable privateCounter, sowie die private Funktion changeBy, die die private Variable verändert. Die Rückgabewerte dieser Funktion sind wiederum drei öffentliche Funktionen, die die private Funktion changeBy nutzen und so eine öffentliche Schnittstelle bilden.

Normalerweise würde man vermuten, dass die privaten Eigenschaften nach Ablauf der Funktion verworfen werden. Da sie allerdings von den öffentlichen Methoden verwendet werden und diese als Rückgabewerte in Counter gespeichert werden, bleibt eine Referenz auf sie bestehen, sodass sie nicht für den Garbage Collector freigegeben werden. Es wurde also eine Closure erstellt. Aus diesem Grund kann über die Funktionen increment, decrement und value immer noch auf die lokale Variable zugegriffen werden.

Closures sind eines der mächtigsten Werkzeuge von JavaScript. Anwendung finden sie meistens nur in Zusammenhang mit Eventhandlern,wenn die Handler-Funktion Zugriff auf ihre eigene Objektinstanz erhalten soll. Ein Grund dafür ist, dass Funktionsaufrufe eine dreimal längere Laufzeit benötigen als das Lookup von Eigenschaftswerten. Implizit werden Closures an verschiedenen Stellen von JavaScript automatisch erstellt. Als ein Beispiel seien die Getter- und Setter-Methoden genannt, die intern über Closures realisiert werden.

[top]