JavaScript ist nicht “irgendeine Programmiersprache”.  Viele, die gute Erfahrung in anderen Sprachen haben, fangen erst gar nicht an JavaScript wirklich lernen zu wollen und sind dann überrascht, wenn auf einmal alles anders läuft als in “irgendeine Programmiersprache”.

JavaScript hat tief im Herzen mehr mit funktionalen Sprachen wie Lisp oder Haskell gemeinsam als mit C oder Java. Leider wissen das nur die wenigsten, weil die Syntax derer von C-Sprachen sehr ähnelt. Z.B. lässt sich die semantische Ähnlichkeit zu Lisp an folgendem Beispiel sehen:

// argFunc ist eine übergebene Funktion die mit
// einem Parameter aufgerufen wird
var func = function(argFunc) {
  argFunc(5);
}
// rufe func mit einer neuen Funktion als Parameter auf
func(function(number) {
  return 5 * number;
});

In Lisp würde das sehr ähnlich funktionieren:

(defun func (lambda (argFunc) (argFunc 5)))
(func lambda(number) (* 5 number))

Funktionale Programmierung mit JavaScript hat viele Vorteile, die unter anderem darin liegen, einige gefährliche Fehlerquellen, die in verschiedenen Designfehlern der Sprache wurzeln, auszublenden (z.B. Verlust von this in geschachtelten Objekten, Abhängigkeiten vom globalen Objekt). Außerdem ist man mit einem funktionalen Ansatz näher an der Natur der Sprache und erreicht eine losere Kopplung und information hiding.

Closures - die größte Stärke von JavaScript
In JavaScript erhalten innere Funktionen Zugang zu Variablen und Parametern, die in der äußeren Funktion definiert wurden. Dieser Zugriff der inneren Funktion auf den Kontext in dem sie erstellt wurde wird durch Closure möglich. Dieses Konzept ist der Grundstein der Mächtigkeit und Ausdruckskraft von JavaScript. Dazu folgende Verständnisbeispiele:

function closure1(myString) {
  var myValue = 1
  , myFunction = function() {
    // die innere Funktion hat Zugriff auf myString und myValue:
    myString += "I'm in a closure";
    myValue += 1;
  };
  return myFunction;
}
// closure1 gibt eine Funktion zurück, die Zugang
// zum inneren Kontext der Funktion 'closure1' hat.
closure1("ohyeah")();

Das obige Beispiel gibt eine Funktion zurück. Mit einem Objekt funktioniert das genauso:

function closure2(myString) {
  var myValue = 1
  , myFunction = function() {
    // die innere Funktion hat Zugriff auf myString und myValue:
    myString += "I'm in a closure";
    myValue += 1;
  };
  return {
    bestFuncEver: myFunction
  };
}
// closure2 gibt ein Objekt zurück, dass eine Funktion
// 'bestFuncEver' enthält, die Zugang zum Kontext der
// Funktion 'closure2' hat.
var myObject = closure2("yeehaa");
myObject.bestFuncEver();

Interessant wird es zuerst mal, wenn Funktionen als Parameter an andere Funktionen übergeben werden, was man am häufigsten aus callback-Mechanismen oder jQuery Funktionsaufrufen (z.B. each) kennt:

function getAFunction(func) {
  var x = 1
  , y = 3;
  func(x, y);
}
function doSomething() {
  var rocks = "scandio rocks!"
  , sucks = "everything else sucks!";
  getAFunction(function(iWantX, iWantY) {
    // In dieser geschachtelten Funktion haben wir nun
    // die Parameter x und y, die in 'getAFunction' übergeben
    // wurden. In dieser geschachtelten Funktion haben wir aber
    // AUCH Zugriff auf die Variablen 'rocks' und 'sucks',
    // die in der äußeren Funktion 'doSomething' gesetzt wurden.
    // Gebe zurück: den Substring des Strings 'rocks' zwischen
    // den Indices die in 'getAFunction' übergeben wurden,
    // in diesem Fall 1 und 3 => "candio"
    return rocks.substring(iWantX, iWantY);
  });
}

Oftmals nimmt man dieses Verhalten als selbstverständlich an. Ist es aber nicht! Das Wichtige : der Kontext der äußeren Funktion bleibt für die innere Funktion erhalten, auch wenn die äußere Funktion den Kontrollfluss längst abgegeben (returnt) hat. Dies ist die Grundlage für viele JavaScript Design patterns, wie z.B. dem Module Pattern (mehr dazu später).
Hier ein einfaches Beispiel zum Nachvollziehen dieses Verhaltens:

function outer() {
  var immortalVar = 'I am immortal through closure!';
  function inner() {
    immortalVar += '-- I can still see immortalVar!';
    return immortalVar;
  }
  // Wir geben ein Objekt zurück und referenzieren
  // die Funktion 'inner' als Property.
  // Auch wenn der Kontrollfluss von 'outer' längst
  // abgegeben ist, hat 'inner' weiterhin
  // Zugriff auf die Variable 'immortalVar'.
  return {
    innerFunc: inner
  };
}
// Außerhalb der Closure
var myObject = outer();
// 'I am immortal through closure!-- I can still see immortalVar!'
myObject.innerFunc();

Zur Laufzeit lassen sich die Scope-Eigenschaften, die sich durch Closures ergeben sehr gut in den Chrome DevTools ergründen, wie mit folgendem Beispiel:

Die Funktion level3 kennt alle Variablen aus den äußeren Closures. Außerdem gut sichtbar ist, dass in der Funktion level3 this das DOMWindow (das globale Objekt) referenziert.

Module Pattern - schlage Nutzen aus Closures
In traditionellen objektorientierten Programmiersprachen gibt es Klassen zum Verstecken von Zuständen und Implementierungen (information hiding), mit dem Ziel von loser Kopplung aller Komponenten. Das gibt es in JavaScript nicht. Das heißt aber nicht, dass es in JavaScript keine Mittel gibt für information hiding und loose coupling. Ein großes Design-Ziel von JS-Applikationen muss letztendlich immer eine Reduzierung von Properties im globalen Objekt sein, am besten nur eine einzige Variable.
Um dies zu erreichen muss man sich in JavaScript funktionaler Programmieransätze und Closures bedienen. Dazu hat sich das Module Pattern als ultimative JavaScript Guideline zur Modularisierung von Komponenten entwickelt. Das folgende Beispiel zeigt wie man dieses Pattern implementieren kann. (Vieles an der Implementierung des Module Patterns ist Stilsache. Die Varitation des folgenden Beispiels hat sich nach meiner Erfahrung als gutes Design erwiesen.)

// MYAPP ist komplett großgeschrieben weil es die einzige Variable
// sein wird die im globalen Objekt gesetzt wird.
// Die Klammer vor (function ist eine Konvention die dem Leser
// sofort sagt: "aha, MYAPP wird nicht die Funktion zugewiesen,
// sondern das Ergebnis dieser Funktion, die sofort ausgeführt
// wird".
var MYAPP = (function() {
  // Alles in dieser Closure ist privat Implementierung/Zustand
  // und nicht von außen zugänglich.
  // Ich schreibe alle privaten Variablen und Funktionen in einer
  // Closure als Konvention mit führendem _Unterstrich für einfache
  // Lesbarkeit.
  var _myVar1 = 1
  , _myVar2 = 'Wohoo, Im so damn private';
  // Die folgende Funktion ist ebenso private und versteckt.
  function _myFunc() {
    // do something incredibly private
  }
  // So, wenn wir jetzt irgendwas innerhalb des Moduls nach außen
  // zugänglich machen wollen brauchen wir ein Interface.
  // Dieses Interface ist das Objekt das die Funktion zurückgibt
  // (kann sowohl ein Objekt als auch eine Funktion sein).
  return {
    myVar1: _myVar1 // veröffentliche _myVar1
    , myFunc: _myFunc // veröffentliche _myFunc
  };
}());
// Der Invocation-Operator () sagt aus, dass die Funktion sofort
// (zur parse-time) ausgeführt wird. Man kann die obige Zeile sowohl
// }()); als auch })(); schreiben. Die Semantik ist die gleiche.
// Die Klammern sind lediglich eine Konvention.

Nachdem dieses Skript geladen ist (parse time), referenziert die Variable das Objekt das von der anonymous self-invoking function zurückgegeben wurde, also das Objekt mit den Properties myVar1 und myFunc. Hier lässt sich jetzt wieder prima die Verhaltensweise von Closures ablesen:

  • die anonyme Funktion in den Klammern hat schon returnt
  • das Objekt das von der Funktion zurückgegeben wurde ist zugreifbar als MYAPP (oder window.MYAPP)
  • die Methoden und Variablen in diesem Objekt greifen weiterhin auf private Funktionen und Variablen in der Closure zu
  • => der Kontext in dem die Funktionen und Variablen erstellt wurden bleibt bestehen, so lange diese Funktionen und Variablen als Properties des Objekts bestehen bleiben

Noch einmal die entscheidende Motivation zur Nutzung des Module-Patterns:

  • Verstecken von internem Zustand und Implementierung.
  • Eliminierung der Nutzung von globalen Variablen und des schlechtesten Features von JavaScript.
  • Es können auch Sub-Module auf einem Modul gesetzt werden, so kann eine Anwendung modularisiert mit einer hierarchischen Architektur aufgebaut werden.
  • Das Module-Pattern gilt als sehr perfomant in allen Browsern.
  • Module sind gekennzeichnet durch lose Kopplung => Module sind unabhängig und lassen sich problemlos entfernen und hinzufügen.
  • Arbeit ist im Team einfacher aufzuteilen, weil Zuständigkeiten in Module gegliedert und an Mitarbeiter zugewiesen werden können.
  • Jedes Modul hat einen lokalen Namespace und kann damit als Sandbox implementiert werden. Dafür müssen die benötigten Abhängigkeiten zur parse time lediglich als Parameter in die Closure übergeben werden.
  • Module sind ohne Probleme nachträglich erweiterbar. (Dies wurde hier nicht besprochen.)
  • Man muss weitaus weniger mit den teils sehr seltsamen Eigenschaften des this -Schlüsselworts kämpfen, weil man, zumindest von der Architektur, einen funktionalen Ansatz verfolgt.

Zusammenfassung
Moderne Webanwendungen zeichnen sich durch immer größere Programmierlogik-Anteile auf Client-Seite aus. Es wird dementsprechend immer wichtiger, auf eine klare Struktur und Architektur des JavaScript-Codes zu setzen. Dafür nutzt man am besten die funktionalen Eigenschaften der Sprache mit Closures und dem Module Pattern. Dieser Artikel könnte dazu einen guten Anstoß geben.