Der Zweck von closures
ist einfach, Zustand zu bewahren ; daher der Name closure
- es schließt sich über Zustand. Zur leichteren Erklärung verwende ich Javascript.
Normalerweise haben Sie eine Funktion
function sayHello(){
var txt="Hello";
return txt;
}
Wobei der Gültigkeitsbereich der Variablen an diese Funktion gebunden ist. Nach der Ausführung verlässt die Variable den txt
Gültigkeitsbereich. Es gibt keine Möglichkeit, darauf zuzugreifen oder sie zu verwenden, nachdem die Ausführung der Funktion abgeschlossen ist.
Closures sind Sprachkonstrukte, mit denen - wie bereits gesagt - der Zustand der Variablen erhalten und damit der Geltungsbereich erweitert werden kann.
Dies kann in verschiedenen Fällen hilfreich sein. Ein Anwendungsfall ist die Konstruktion von Funktionen höherer Ordnung .
In Mathematik und Informatik ist eine Funktion höherer Ordnung (auch funktionale Form, Funktion oder Funktor) eine Funktion, die mindestens eine der folgenden Aufgaben erfüllt: 1
- Nimmt eine oder mehrere Funktionen als Eingabe an
- gibt eine Funktion aus
Ein einfaches, aber zugegebenermaßen nicht allzu nützliches Beispiel ist:
makeadder=function(a){
return function(b){
return a+b;
}
}
add5=makeadder(5);
console.log(add5(10));
Sie definieren eine Funktion makedadder
, die einen Parameter als Eingabe verwendet und eine Funktion zurückgibt . Es gibt eine äußerefunction(a){}
und eine innere Funktion. function(b){}{}
Außerdem definieren Sie (implizit) eine andere Funktion add5
als Ergebnis des Aufrufs der Funktion höherer Ordnung makeadder
. makeadder(5)
gibt eine anonyme ( innere ) Funktion zurück, die wiederum 1 Parameter und die Summe der Parameter der äußeren Funktion und der Parameter der inneren Funktion zurückgibt .
Der Trick ist, dass bei der Rückgabe der inneren Funktion, die das eigentliche Hinzufügen vornimmt, der Gültigkeitsbereich des Parameters der äußeren Funktion ( a
) erhalten bleibt. add5
erinnert sich , dass der Parameter a
war 5
.
Oder um ein zumindest irgendwie nützliches Beispiel zu zeigen:
makeTag=function(openTag, closeTag){
return function(content){
return openTag +content +closeTag;
}
}
table=makeTag("<table>","</table>")
tr=makeTag("<tr>", "</tr>");
td=makeTag("<td>","</td>");
console.log(table(tr(td("I am a Row"))));
Ein weiterer häufiger Anwendungsfall ist der sogenannte IIFE = sofort aufgerufene Funktionsausdruck. In Javascript ist es sehr verbreitet, private Mitgliedsvariablen zu fälschen . Dies geschieht über eine Funktion, die einen privaten Gültigkeitsbereich = erzeugt closure
, da dieser unmittelbar nach dem Definitionsaufruf aufgerufen wird. Die Struktur ist function(){}()
. Beachten Sie die Klammern ()
nach der Definition. Dies macht es möglich, es für die Objekterstellung mit aufschlussreichem Modulmuster zu verwenden . Der Trick besteht darin, einen Bereich zu erstellen und ein Objekt zurückzugeben, das nach Ausführung des IIFE Zugriff auf diesen Bereich hat.
Das Beispiel von Addi sieht so aus:
var myRevealingModule = (function () {
var privateVar = "Ben Cherry",
publicVar = "Hey there!";
function privateFunction() {
console.log( "Name:" + privateVar );
}
function publicSetName( strName ) {
privateVar = strName;
}
function publicGetName() {
privateFunction();
}
// Reveal public pointers to
// private functions and properties
return {
setName: publicSetName,
greeting: publicVar,
getName: publicGetName
};
})();
myRevealingModule.setName( "Paul Kinlan" );
Das zurückgegebene Objekt enthält Verweise auf Funktionen (z. B. publicSetName
), die wiederum Zugriff auf "private" Variablen haben privateVar
.
Dies sind jedoch speziellere Anwendungsfälle für Javascript.
Welche spezifische Aufgabe würde ein Programmierer ausführen, die durch einen Abschluss am besten bedient werden könnte?
Dafür gibt es mehrere Gründe. Man könnte sein, dass es für ihn selbstverständlich ist, da er einem funktionalen Paradigma folgt . Oder in Javascript: Es ist nur die Notwendigkeit , sich auf Verschlüsse zu verlassen, um einige Macken der Sprache zu umgehen.