Das berüchtigte Problem der JavaScript-Schleife tritt auf, wenn versucht wird, Ereignishandler mithilfe einer Schleife an dynamisch generierte Elemente anzuhängen. Im folgenden Snippet:
function addLinks() { for (var i = 0, link; i < 5; i++) { link = document.createElement("a"); link.innerHTML = "Link " + i; link.onclick = function () { alert(i); // WRONG: i will always be 5 }; document.body.appendChild(link); } }
Wenn auf einen der generierten Links geklickt wird, zeigt die Warnung immer „Link 5“ an. Dies liegt daran, dass die mit var definierten JavaScript-Variablen funktionsbezogen und nicht blockbezogen sind. Wenn die Schleife endet, enthält i den Wert 5 und alle inneren Funktionen verweisen darauf, was zur einheitlichen Ausgabe führt.
Die korrigierte Lösung besteht darin, den Wert von i innerhalb eines Abschlusses zu erfassen. Betrachten Sie diesen Ausschnitt:
function addLinks() { for (var i = 0, link; i < 5; i++) { link = document.createElement("a"); link.innerHTML = "Link " + i; link.onclick = function (num) { // Closure around i return function () { alert(num); // num retains its original value }; }(i); // Execute the outer function immediately to capture i document.body.appendChild(link); } }
In diesem Fall ist num für jede Iteration an den aktuellen Wert von i gebunden. Wenn die innere Funktion ausgeführt wird, wird num zum Zeitpunkt der Schleifenausführung konsistent auf den Wert von i gesetzt.
Darüber hinaus gibt es eine effiziente Alternative, die den DOM-Knoten zum Speichern von Daten nutzt:
function linkListener() { alert(this.i); } function addLinks() { for (var i = 0; i < 5; ++i) { var link = document.createElement('a'); link.appendChild(document.createTextNode('Link ' + i)); link.i = i; link.onclick = linkListener; document.body.appendChild(link); } }
Durch das Anhängen von Informationen an das DOM-Element selbst wird der Bedarf an zusätzlichen Funktionsobjekten umgangen und die Effizienz verbessert.
Das obige ist der detaillierte Inhalt vonWarum gibt meine JavaScript-Schleife beim Anhängen von Ereignishandlern immer den Endwert der Zählervariablen aus?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!