Erstens, im Gegensatz zu dem, was die meisten Leute hier sagen, Verschluss ist pas eine Funktion ! Was also es es?
Es ist ein einstellen. von Symbolen, die im "umgebenden Kontext" einer Funktion definiert sind (bekannt als ihr Umwelt ), die ihn zu einem GESCHLOSSENEN Ausdruck machen (d.h. ein Ausdruck, in dem jedes Symbol definiert ist und einen Wert hat, so dass er ausgewertet werden kann).
Zum Beispiel, wenn Sie eine JavaScript-Funktion haben:
function closed(x) {
return x + 3;
}
Es ist ein geschlossener Ausdruck weil alle darin vorkommenden Symbole darin definiert sind (ihre Bedeutung ist klar), so dass man sie auswerten kann. Mit anderen Worten, sie ist Eigenständig .
Aber wenn Sie eine Funktion wie diese haben:
function open(x) {
return x*y + 3;
}
es ist ein offener Ausdruck weil sie Symbole enthält, die darin nicht definiert sind. Nämlich, y
. Wenn wir uns diese Funktion ansehen, können wir nicht sagen, was y
ist und was er bedeutet, kennen wir nicht, so dass wir diesen Ausdruck nicht auswerten können. D.h. wir können diese Funktion erst aufrufen, wenn wir wissen, was y
darin bedeuten soll. Diese y
wird als freie Variable .
Diese y
bittet um eine Definition, aber diese Definition ist nicht Teil der Funktion - sie wird an anderer Stelle definiert, in ihrem "umgebenden Kontext" (auch bekannt als die Umwelt ). Zumindest hoffen wir das :P
Sie könnte zum Beispiel global definiert werden:
var y = 7;
function open(x) {
return x*y + 3;
}
Oder sie könnte in einer Funktion definiert werden, die sie umschließt:
var global = 2;
function wrapper(y) {
var w = "unused";
return function(x) {
return x*y + 3;
}
}
Der Teil der Umgebung, der den freien Variablen in einem Ausdruck ihre Bedeutung gibt, ist die Verschluss . Sie wird so genannt, weil sie ein öffnen Ausdruck in eine geschlossen ein, indem sie diese fehlenden Definitionen für alle ihre freie Variablen damit wir sie bewerten können.
Im obigen Beispiel ist die innere Funktion (der wir keinen Namen gegeben haben, weil wir sie nicht brauchen) eine offener Ausdruck weil die Variable y
Darin ist kostenlos - ihre Definition liegt außerhalb der Funktion, in der Funktion, die sie umhüllt. Die Umwelt für diese anonyme Funktion ist die Menge der Variablen:
{
global: 2,
w: "unused",
y: [whatever has been passed to that wrapper function as its parameter `y`]
}
Nun, die Verschluss ist der Teil dieser Umwelt, der schließt die innere Funktion durch Angabe der Definitionen für alle ihre freie Variablen . In unserem Fall war die einzige freie Variable in der inneren Funktion y
so dass der Abschluss dieser Funktion diese Teilmenge ihrer Umgebung ist:
{
y: [whatever has been passed to that wrapper function as its parameter `y`]
}
Die beiden anderen in der Umgebung definierten Symbole sind pas Teil des Verschluss dieser Funktion, da sie für die Ausführung nicht erforderlich sind. Sie werden nicht benötigt, um schließen es.
Mehr über die Theorie dahinter erfahren Sie hier: https://stackoverflow.com/a/36878651/434562
Es ist erwähnenswert, dass im obigen Beispiel die Wrapper-Funktion ihre innere Funktion als Wert zurückgibt. Der Zeitpunkt, zu dem wir diese Funktion aufrufen, kann zeitlich weit von dem Zeitpunkt entfernt sein, zu dem die Funktion definiert (oder erstellt) wurde. Insbesondere läuft die Wrapper-Funktion nicht mehr, und ihre Parameter, die sich auf dem Aufrufstapel befanden, sind nicht mehr da :P Das ist ein Problem, denn die innere Funktion benötigt y
da zu sein, wenn sie aufgerufen wird! Mit anderen Worten, die Variablen aus der Schließung müssen irgendwie überleben die Wrapper-Funktion und ist da, wenn sie gebraucht wird. Daher muss die innere Funktion eine Schnappschuss dieser Variablen, die den Abschluss bilden, und speichert sie an einem sicheren Ort zur späteren Verwendung. (Irgendwo außerhalb des Aufrufstapels.)
Aus diesem Grund wird der Begriff oft verwechselt Verschluss zu dieser speziellen Art von Funktion gehören, die solche Schnappschüsse der externen Variablen, die sie verwenden, oder der Datenstruktur, die zur Speicherung dieser Variablen für spätere Zwecke verwendet wird, erstellen kann. Aber ich hoffe, Sie verstehen jetzt, dass es sich um pas die Schließung selbst - sie sind nur Mittel, um implementieren Abschlüsse in einer Programmiersprache oder Sprachmechanismen, die es ermöglichen, dass die Variablen des Funktionsabschlusses bei Bedarf zur Verfügung stehen. Es gibt eine Menge Missverständnisse rund um Closures, die dieses Thema (unnötigerweise) viel verwirrender und komplizierter machen, als es eigentlich ist.
33 Stimmen
Was genau ist nun der Abschluss? Einige Antworten besagen, dass der Abschluss die Funktion ist. Andere sagen, es ist der Stapel. In einigen Antworten heißt es, es sei der "versteckte" Wert. Nach meinem Verständnis ist es die Funktion + eingeschlossene Variablen.
5 Stimmen
Erklärt, was ein Abschluss ist: stackoverflow.com/questions/4103750/
2 Stimmen
Sehen Sie sich auch an Was ist ein Abschluss? bei softwareengineering.stackexchange
0 Stimmen
Hier gibt es tolle Antworten. Dennoch lohnt es sich, darauf einzugehen stackoverflow.com/a/36878651/1029599 insbesondere, wenn Sie mathematisch begabt sind.