CSS, HTML und Javascript mit {stil}

Innere Funktionen / Closures

Closure: Javascript function in a function

ECMAScript erlaubt innere Funktionen: Die Definition und die Anweisungen einer inneren Funktion sitzen innerhalb einer anderen Funktion.

Die innere Funktion kann auf alle lokalen Variablen, auf die Argumente und andere innere Funktionen der umfassenden Funktion zugreifen.

Funktionen in Javascript sind Objekte und können wie jeder andere Datentyp einer Variablen als Wert zugewiesen werden – wenn eine Funktion z.B. einen Integer-Wert zurückgibt, wird sie wie ein Integer behandelt.

JavaScript-Funktionen sind Objekte, und zwar »Objekte höherer Ordnung«. Darum können sie als Parameter an andere Funktionen übergeben und wie jedes andere Objekt (String, Array, Number, …) verwendet werden:

  • Funktionen können in Variablen gespeichert werden und können der Rückgabewert einer Funktion sein.
  • In Javascript dürfen Funktionen in Funktionen erzeugt werden – ein Feature, dass es nur in wenigen Programmiersprachen gibt.
  • Funktionen, die einen Rückgabewert liefern, können als Argumente in Funktionen eingesetzt werden.

Da Funktionen Objekt sind, werden sie als Referenz übergeben und nicht als Wert (siehe auch call by reference und call by value).

var summe = steuer (checkNum(betrag), checkNum(mwstSatz));

function steuer(betrag, satz) {
   return (betrag + betrag * satz / 100);
}

function checkNum(obj) {
   if (isNaN(parseInt(obj.value))) {
      return 0;
   } else {
      return parseInt(obj.value);
   }
}

Der Rückgabewert von checkNum() muss nicht in einer Variablen gespeichert werden, sondern die Funktion sitzt direkt als Argument in steuer():

steuer( checkNum( betrag), checkNum( mwstSatz) )

Javascript Closures

Seit Javascript 1.5 kann eine innere Funktion sogar innerhalb eines Anweisungsblocks erzeugt werden. Allerdings sind dann nur Funktionsaufrufe innerhalb des Blocks zugelassen.

Beim Aufruf der äußeren Funktion (also bei der Ausführung) erzeugt der Javascript-Interpreter den Code der inneren Funktion. Dabei entsteht ein „Closure" der inneren Funktion – das ist der Code der Funktion und eine Referenz auf alle Variablen, die von der inneren Funktion benötigt werden (die innere Funktion hat Zugriff auf die Variablen und Parameter der äußeren Funktion).

Javascript Closure – Scope
Der »Scope« – der Güligkeitsbereich von Variablen

Ein Closure ist eine Funktion, die Zugriff auf den Scope ihrer umfassenden Funktion hat, selbst nachdem die umschließende Funktion abgeschlossen wurde.

Closures kombinieren den Programmcode mit der lexikalischen Umgebung – d.h., ein Closure merkt sich die Umgebung, in der es erzeugt wurde.

Hinweis: Closures machen es möglich, private Instanzvariablen in Objekten zu definieren.

Closures haben ihre Schattenseiten: Sie sind anfällig für Memory Leaks und sind langsamer als eine innere Funktion ohne Closure und viel langsamer als eine statische Funktion.

function initAlert () {
   var msg = "Was noch zu sagen wäre";
   window.setTimeout (function () {alert (msg); }, 100);
}

ist langsamer als

function initAlert () {
    window.setTimeout ( function () {
        var msg = "Was noch zu sagen wäre";
        alert (msg);
    }, 100);
}

und auch diese Variante ist langsamer als

function alertMsg() {
   var msg = "Was noch zu sagen wäre";
   alert (msg);
}

function initAlert () {
    window.setTimeout (alertMsg, 100);
}

Closures erzeugen einen zusätzlichen Level in der Tiefe der Scopes, den der Browser auflösen, bevorraten und prüfen muss.

Javascript Callback

So, das ist schon ausgesprochen esoterisch.

Callback-Funktionen sind ein einfacheres Konzept. Ein Callback entsteht, wenn eine Funktion eine Funktion als Parameter zulässt. An irgendeinem Punkt der Ausführung wird die Funktion die Callback-Funktion ausführen – das ist das Callback am Callback. Callback-Funktionen werden oft bei der asynchronen Verarbeitung von Events eingesetzt – die Funktion kann fertig ausgeführt sein und die Steuerung bereits zurückgegeben haben, wenn die Callback-Funktion aufgerufen wird.

Callbacks kennen wir seit ewig und mehr Jahren aus setTimeout() und setInterval() (und auch requestAnimationFrame setzt auf Callbacks), und anderen Funktionen von window.

function fn() { alert('Hier ist ein Callback') }
window.setTimeout(fn, 5000);

… 

elem.addEventListener ('click', myfunction );

Stark vereinfacht ist ein Callback ausführbarer Code, der als Parameter übergeben wird.

Mehr zu Javascript Funktionen

First Class