Bei einem Beispiel handelt es sich um eine Schließung, bei dem anderen nicht. Das Implementieren von Closures ist etwas knifflig, da Closed-Over-Variablen nicht wie normale Variablen funktionieren. Dies ist in einer einfachen Sprache wie C offensichtlicher, aber ich werde JavaScript verwenden, um dies zu veranschaulichen.
Ein Closure besteht nicht nur aus einer Funktion, sondern auch aus allen Variablen, über die es geschlossen hat. Wenn wir diese Funktion aufrufen möchten, müssen wir auch alle Variablen bereitstellen, die geschlossen sind. Wir können einen Abschluss durch eine Funktion modellieren, die ein Objekt als erstes Argument empfängt, das diese über Variablen geschlossenen Werte darstellt:
function add(vars, y) {
vars.x += y;
}
function getSum(vars) {
return vars.x;
}
function makeAdder(x) {
return { x: x, add: add, getSum: getSum };
}
var adder = makeAdder(40);
adder.add(adder, 2);
console.log(adder.getSum(adder)); //=> 42
Beachten Sie die closure.apply(closure, ...realArgs)
dazu erforderliche umständliche Aufrufkonvention
Die integrierte Objektunterstützung von JavaScript ermöglicht es, das explizite vars
Argument wegzulassen und this
stattdessen Folgendes zu verwenden :
function add(y) {
this.x += y;
}
function getSum() {
return this.x;
}
function makeAdder(x) {
return { x: x, add: add, getSum: getSum };
}
var adder = makeAdder(40);
adder.add(2);
console.log(adder.getSum()); //=> 42
Diese Beispiele entsprechen dem Code, der tatsächlich Abschlüsse verwendet:
function makeAdder(x) {
return {
add: function (y) { x += y },
getSum: function () { return x },
};
}
var adder = makeAdder(40);
adder.add(2);
console.log(adder.getSum()); //=> 42
In diesem letzten Beispiel wird das Objekt nur zum Gruppieren der beiden zurückgegebenen Funktionen verwendet. Die this
Bindung ist irrelevant. Alle Details zur Ermöglichung von Schließungen - die Übergabe versteckter Daten an die eigentliche Funktion, die Änderung aller Zugriffe auf Schließungsvariablen, um in diesen versteckten Daten nachzuschlagen - werden von der Sprache erledigt.
Das Aufrufen von Closures bedeutet jedoch den Mehraufwand für das Übergeben dieser zusätzlichen Daten, und das Ausführen eines Closures bedeutet den Mehraufwand für das Nachschlagen dieser zusätzlichen Daten - der durch eine schlechte Cache-Lokalität und normalerweise eine Zeiger-Dereferenzierung im Vergleich zu normalen Variablen verschlechtert wird -, so dass dies nicht verwunderlich ist Eine Lösung, die nicht auf Verschlüssen beruht, bietet eine bessere Leistung. Zumal alles, was Sie mit Ihrem Verschluss ersparen, ein paar extrem kostengünstige Rechenoperationen sind, die beim Parsen sogar konstant gefaltet werden können.