Heim >Web-Frontend >js-Tutorial >Warum verursachen Javascript-Schleifen unerwartetes Verhalten in Event-Handlern?
Das berüchtigte Schleifenproblem in Javascript erneut aufgegriffen
Das berüchtigte Schleifenproblem in Javascript stellt Entwickler weiterhin vor ein Rätsel. Betrachten Sie den folgenden Codeausschnitt:
function addLinks () { for (var i=0, link; i<5; i++) { link = document.createElement("a"); link.innerHTML = "Link " + i; link.onclick = function () { alert(i); }; document.body.appendChild(link); } }
Dieser Code soll 5 Links erstellen, jeder mit einem onClick-Ereignis, das die aktuelle Link-ID anzeigt. Wenn jedoch auf diese Links geklickt wird, wird für alle „Link 5“ angezeigt.
Die Hauptursache für dieses Problem liegt im Scoping auf Funktionsebene von Javascript. Wenn die Schleife abgeschlossen ist, behält die i-Variable den Wert 5. Dies liegt daran, dass Javascript-Funktionen über ihre lexikalische Umgebung geschlossen sind, was bedeutet, dass sie Zugriff auf die im umgebenden Bereich definierten Variablen haben.
Eine Problemumgehung für dieses Problem besteht darin, einen Abschluss einzuführen, der den aktuellen Wert von i für jede Iteration erfasst:
function addLinks () { for (var i=0, link; i<5; i++) { link = document.createElement("a"); link.innerHTML = "Link " + i; link.onclick = function (num) { return function () { alert(num); }; }(i); document.body.appendChild(link); } }
In diesem Code wird für jeden Link ein neues Funktionsobjekt erstellt. Es verfügt über einen eigenen Gültigkeitsbereich und eine lokale Variable num, der der aktuelle Wert von i zugewiesen wird. Wenn die innere Funktion ausgeführt wird, verweist sie auf die Num-Variable des Abschlusses, die den korrekten, in der Schleife zugewiesenen Wert beibehält.
Dieser Ansatz ist zwar effektiv, führt jedoch zu Leistungseinbußen, wenn eine neue Funktion erstellt wird für jeden Event-Listener. Eine effizientere Alternative besteht darin, den DOM-Knoten selbst für die Datenspeicherung zu verwenden:
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 die direkte Speicherung des i-Werts auf dem DOM-Knoten machen wir Abschlüsse überflüssig und verbessern so die Effizienz des Codes.
Das obige ist der detaillierte Inhalt vonWarum verursachen Javascript-Schleifen unerwartetes Verhalten in Event-Handlern?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!