
JavaScript 臭名昭著的循環異常:解釋
當嘗試使用循環將事件處理程序附加到動態生成的元素時,就會出現臭名昭著的JavaScript 循環問題。在以下程式碼片段中:
1 2 3 4 5 6 7 8 9 10 | 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);
}
}
|
登入後複製
點擊任何產生的連結時,警報始終顯示「連結 5」。這是因為用 var 定義的 JavaScript 變數是函數作用域的,而不是區塊作用域的。當迴圈結束時,i 保持值 5,所有內部函數都會引用它,從而得到統一的輸出。
修正的解決方案在於捕捉閉包內 i 的值。考慮這個片段:
1 2 3 4 5 6 7 8 9 10 11 12 | 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);
}
}
|
登入後複製
在這種情況下,num 綁定到每次迭代的 i 的當前值。執行內部函數時,num 總是設定為循環執行時 i 的值。
此外,存在一種利用DOM 節點儲存資料的有效替代方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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);
}
}
|
登入後複製
透過將資訊附加到DOM 元素本身,避免了對額外函數物件的需求,從而提高了效率。
以上是為什麼我的 JavaScript 迴圈在附加事件處理程序時總是輸出計數器變數的最終值?的詳細內容。更多資訊請關注PHP中文網其他相關文章!