Mit Closures können JavaScript-Programmierer besseren Code schreiben. Kreativ, ausdrucksstark und prägnant. Wir verwenden häufig Closures in JavaScript, und unabhängig von unserer JavaScript-Erfahrung werden wir ihnen zweifellos immer wieder begegnen. Closures mögen komplex erscheinen, aber nach der Lektüre dieses Artikels werden sie hoffentlich viel leichter zu verstehen sein und somit für Ihre täglichen JavaScript-Programmieraufgaben attraktiver werden.
Sie sollten vertraut sein mit Umfang von JavaScript-Variablen bevor Sie weiter lesen, denn um Closures zu verstehen, müssen Sie den Variablenbereich von JavaScript verstehen.
Was ist ein Abschluss?
Eine Closure ist eine innere Funktion, die Zugriff auf die Variablen-Umfangskette der äußeren (einschließenden) Funktion hat. Die Closure hat drei Scope-Ketten: Sie hat Zugriff auf ihren eigenen Scope (Variablen, die zwischen ihren geschweiften Klammern definiert sind), sie hat Zugriff auf die Variablen der äußeren Funktion und sie hat Zugriff auf die globalen Variablen.
Die innere Funktion hat nicht nur Zugriff auf die Variablen der äußeren Funktion, sondern auch auf die Parameter der äußeren Funktion. Beachten Sie jedoch, dass die innere Funktion das Argumente-Objekt der äußeren Funktion nicht aufrufen kann, auch wenn sie die Parameter der äußeren Funktion direkt aufrufen kann.
Sie erstellen einen Abschluss, indem Sie eine Funktion innerhalb einer anderen Funktion hinzufügen.
Ein grundlegendes Beispiel für Closures in JavaScript:
function showName (firstName, lastName) {
var nameIntro = "Your name is ";
// this inner function has access to the outer function's variables, including the parameter
function makeFullName () {
return nameIntro + firstName + " " + lastName;
}
return makeFullName ();
}
showName ("Michael", "Jackson"); // Your name is Michael Jackson
Closures werden in Node.js ausgiebig verwendet; sie sind die Arbeitspferde der asynchronen, nicht-blockierenden Architektur von Node.js. Closures werden auch häufig in jQuery und so ziemlich jedem Stück JavaScript-Code verwendet, das Sie lesen.
Ein klassisches jQuery-Beispiel für Closures:
$(function() {
var selections = [];
$(".niners").click(function() { // this closure has access to the selections variable
selections.push (this.prop("name")); // update the selections variable in the outer function's scope
});
});
Regeln und Nebenwirkungen von Schließungen
1. Closures haben auch nach der Rückkehr der äußeren Funktion Zugriff auf die Variable der äußeren Funktion:
Eine der wichtigsten und heikelsten Eigenschaften von Closures ist, dass die innere Funktion immer noch Zugriff auf die Variablen der äußeren Funktion hat, selbst nachdem die äußere Funktion zurückgekehrt ist. Ja, Sie haben das richtig gelesen. Wenn Funktionen in JavaScript ausgeführt werden, verwenden sie dieselbe Gültigkeitsbereichskette, die beim Erstellen der Funktion in Kraft war. Das bedeutet, dass die innere Funktion auch nach der Rückkehr der äußeren Funktion noch Zugriff auf die Variablen der äußeren Funktion hat. Daher können Sie die innere Funktion später in Ihrem Programm aufrufen. Dieses Beispiel demonstriert dies:
function celebrityName (firstName) {
var nameIntro = "This celebrity is ";
// this inner function has access to the outer function's variables, including the parameter
function lastName (theLastName) {
return nameIntro + firstName + " " + theLastName;
}
return lastName;
}
var mjName = celebrityName ("Michael"); // At this juncture, the celebrityName outer function has returned.
// The closure (lastName) is called here after the outer function has returned above
// Yet, the closure still has access to the outer function's variables and parameter
mjName ("Jackson"); // This celebrity is Michael Jackson
2. Closures speichern Referenzen auf die Variablen der äußeren Funktion:
Sie speichern nicht den tatsächlichen Wert. Closures werden noch interessanter, wenn sich der Wert der Variablen der äußeren Funktion ändert, bevor die Closure aufgerufen wird. Und diese leistungsstarke Funktion kann auf kreative Weise genutzt werden, wie dieses Beispiel für private Variablen, das erstmals von Douglas Crockford gezeigt wurde:
function celebrityID () {
var celebrityID = 999;
// We are returning an object with some inner functions
// All the inner functions have access to the outer function's variables
return {
getID: function () {
// This inner function will return the UPDATED celebrityID variable
// It will return the current value of celebrityID, even after the changeTheID function changes it
return celebrityID;
},
setID: function (theNewID) {
// This inner function will change the outer function's variable anytime
celebrityID = theNewID;
}
}
}
var mjID = celebrityID (); // At this juncture, the celebrityID outer function has returned.
mjID.getID(); // 999
mjID.setID(567); // Changes the outer function's variable
mjID.getID(); // 567: It returns the updated celebrityId variable
3. Schiefgelaufene Schließungen
Da Closures Zugriff auf die aktualisierten Werte der Variablen der äußeren Funktion haben, können sie auch zu Fehlern führen, wenn sich die Variable der äußeren Funktion mit einer for-Schleife ändert. Daher:
// This example is explained in detail below (just after this code box).
function celebrityIDCreator (theCelebrities) {
var i;
var uniqueID = 100;
for (i = 0; i < theCelebrities.length; i++) {
theCelebrities[i]["id"] = function () {
return uniqueID + i;
}
}
return theCelebrities;
}
var actionCelebs = [{name:"Stallone", id:0}, {name:"Cruise", id:0}, {name:"Willis", id:0}];
var createIdForActionCelebs = celebrityIDCreator (actionCelebs);
var stalloneID = createIdForActionCelebs [0]; console.log(stalloneID.id()); // 103
Mehr dazu finden Sie hier.
-
http://javascript.info/tutorial/closures
-
http://www.javascriptkit.com/javatutors/closures.shtml