JavaScript Coding Patterns: Closures & Immediate Functions

Avatar von Norbert Schmidt

Dies ist der zweite Teil der Reihe JavaScript Coding Patterns. Der erste Teil handelt vom Einsatz von Objekt-Literalen zur Strukturierung von JavaScript-Code. Nun geht es um Closures und Immediate Functions und darum, wie sich mit deren Hilfe private und öffentliche Eigenschaften von JavaScript-Objekten umsetzen lassen.

Funktionen als Objekte

JavasScript ist eine funktionale Sprache und räumt naturgemäß Funktionen einen wichtigen Stellenwert ein. Funktionen sind in JavaScript First-Class Objects. Sie haben Attribute und Methoden, werden an Funktionen als Argumente übergeben, können Variablen als Werte zugewiesen werden und lassen sich dynamisch, zur Laufzeit, definieren. Und Javascript-Funktionen erzeugen Scope.

Vor allem auf das zuletzt genannte Merkmal von JavaScript-Funktionen gehe ich im Folgenden ein und stelle vor diesem Hintergrund die Verwendung von Closures und Immediate Functions als Coding Patterns dar.

Scope

Nur Funktionen stellen in JavaScript lokale Sichtbarkeitsbereiche von Variablen zur Verfügung. In JavaScript gibt es keinen Curly Braces Scope (resp. Block Scope), sondern nur Function Scope. Mit einer Funktion lässt sich also die Sichtbarkeit von Variablen regeln, lässt sich festlegen, was private und was public ist. Jede Funktion hat Zugriff auf ihren eigenen Kontext und zusätzlich auf den aller ihrer Eltern. Das wird die Scope Chain genannt. Im nachfolgenden Beispiel hat die innerste Funktion core() Zugriff auf ihre eigenen und auf alle entlang der Scope Chain stehenden Variablen:

var globalVar = 1;

var outer = function () {
    var outerVar = 2

    var inner = function () {
        var innerVar = 3;

        var core = function () {
            var coreVar = 4;
            return coreVar + innerVar + outerVar + globalVar;
        };

        return core();
    };

    return inner();
};

outer(); // 10

Für den Fall, dass in den verschachtelten und verketteten Kontexten Namenskonflikte auftreten, weil lokale Variablen den gleichen Namen wie globale erhalten haben, überlagern die lokalen Definitionen die globalen. Der lokale Scope gewinnt immer!

Closures

Bereits das Beispiel der Scope Chain zeigt eine Closure in Aktion. Eine Closure ist eine Funktion, die eine andere Funktion umrahmt. Mit Hilfe solcher Konstrukte kann in JavaScript Datenkapselung realisiert werden. Das ist im nächsten Code-Listing noch einmal genauer zu sehen:

var application = function () {
    var name = 'Awesome Application';

    var version = 'v0.0.1';

    var init = function () {
        var msg = 'Successfully launched: ';
        return msg + name + ', ' + version;
    };

    return init;
};

var initApp = application();

initApp(); // 'Successfully launched: Awesome Application, v0.0.1'

Der Rückgabewert von application() ist die Funktion init(). JavaScript-Funktionen können eben auch Funktionen zurückliefern und nicht nur einfache Daten, Arrays oder Objekte. Die hier zurückgegebene Funktion hat neben ihrem eigenen Scope auch Zugriff auf den sie umgebenden Kontext und kann darum private Daten von application auslesen. Diesen Einschluss einer Funktion in einer anderen Funktion nennt man allgemein Closure, einen Funktionsabschluss.

Was eine Closure ausmacht, ist die Tatsache, dass hier eine Funktion immer eine Verknüpfung zu dem Kontext behält, in dem sie definiert wurde. Im oben gezeigten Beispiel kann über die globale Variable initApp, die auf den ersten Blick nur eine einfache Funktionsreferenz zu sein scheint, auf die lokalen Variablen von application zugegriffen werden. Und das sogar nachdem application() ihren Rückgabewert geliefert hat, wodurch auch ihr Scope zerstört wurde. Die weiter oben beschriebene Scope Chain ist somit aufgebrochen.

Eine Closure ist so gesehen ein ausführbares Stück Code, das in andere Kontexte hineingereicht werden kann und immer noch Zugriff auf Daten seines Entstehungskontextes hat. Dabei erfolgt der Zugriff per Referenz, nicht als Kopie.

Immediate Functions

Ein weiterer interessanter und verbreiteter Anwendungsfall für Funktionen ist die sogenannte Immediate Function. Damit wird eine Funktion bezeichnet, die bereits mit ihrer Definition ausgeführt wird:

(function () {
    return 'In an instant!';
})();

In diesem Fall wird eine anonyme Funktion, ein bloßer Funktionsausdruck, keiner Variablen zugewiesen. Das ist der Grund dafür, dass der Ausdruck in Klammern gefasst werden muss. Das entscheidende Detail ist aber das abschließende Paar runder Klammern, der Function Call Operator. Er sorgt dafür, dass die anonyme Funktion unmittelbar aufgerufen und der Code in ihr direkt ausgeführt wird. Der Operator bietet selbstverständlich noch die Möglichkeit, Argumente an die anonyme Funktion zu übergeben:

(function (name) {
    return 'Hello ' + name;
})('Willy');

// 'Hello Willy!'

Eine Immediate Function kann z.B. dazu verwendet werden, Prozesse anzustoßen, die initial, vor allen anderen, laufen müssen. Übrigens, viele JavaScript Bibliotheken nutzen eine Immediate Function um ihren Namensraum zu definieren und zu sichern. So besteht beispielsweise der Quellcode von jQuery aus einer einzigen großen Funktion dieser Art.

Fazit

Closures und Immediate Functions sind in jedem Fall dazu geeignet, auch komplexem Code einen Rahmen zu geben. Mit Closures lassen sich private und öffentliche Eigenschaften und Methoden sehr flexibel realisieren, ohne das in JavaScript Konzepte wie public und private existieren. Und mit Immediate Functions können auch größere Code-Blöcke in einem Scope zusammengefasst und sogar direkt ausgeführt werden.

Im dritten Teil der Reihe JavaScript Coding Patterns wird es um die Kombination von Closures und Immediate Functions gehen, um das sogenannte Module Pattern.

Weiter lesen und lernen!

Avatar von Norbert Schmidt

Kommentare

3 Antworten zu „JavaScript Coding Patterns: Closures & Immediate Functions“

  1. Lesenswert: JavaScript Coding Patterns: Closures & Immediate Functions http://t.co/p73f6lMrt1

  2. JavaScript Coding Patterns: Closures & Immediate Functions http://t.co/3N1uOyCpjv via @mayflowerphp

  3. Avatar von Ulrich Eckardt
    Ulrich Eckardt

    Coole Sache. Das gute ist, man kann das auch wunderbar in Plug-Ins für diverse CMS-Systeme nutzen. Jedenfalls schaut der Code einfach, verständlich und nachvollziehbar aus.

    Vielen Dank

    Ulrich Eckardt

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert


Für das Handling unseres Newsletters nutzen wir den Dienst HubSpot. Mehr Informationen, insbesondere auch zu Deinem Widerrufsrecht, kannst Du jederzeit unserer Datenschutzerklärung entnehmen.