2013-02-22 64 views
-1

JavaScript中奇怪的「懶惰」行爲。這個工作正常:JavaScript中涉及懶惰的一種奇怪行爲

$(document).on("change", "#dropdown-menu-category-chk", function(){ 
    $("#dropdown-menu-category input[type='checkbox']").prop('checked', this.checked); 
}); 

$(document).on("change", "#dropdown-menu-category2-chk", function(){ 
    $("#dropdown-menu-category2 input[type='checkbox']").prop('checked', this.checked); 
}); 

$(document).on("change", "#dropdown-menu-category3-chk", function(){ 
    $("#dropdown-menu-category3 input[type='checkbox']").prop('checked', this.checked); 
}); 

// and so on.... 

但是在這段代碼中變量i == 5!

function setDropDowns(){ 
    var idList = ['category', 'category2', 'category3', 'category4', 'category5'] 
    for(var i = 0; i < idList.length; i++){ 
    $(document).on("change", "#dropdown-menu-"+idList[i]+"-chk", function(){ 
     $("#dropdown-menu-" +idList[i] +" input[type='checkbox']").prop('checked', this.checked); 
     debugger; // i == 5; idList[i] === undefined 
    }); 
    } 
} 

即使我說

for(var i = 0; i < idList.length; i++){ 
    var id = dropDownCheckBoxItemList[i]; 
    $(document).on("change", "#dropdown-menu-"+id+"-chk", function(){ 

它不會工作,因爲id將等於'category5'時的代碼會被執行!

如何使用循環工作?我不想打破DRY的規則。

+0

順便說一句,字符串'「#下拉菜單,菜單 - 」 + ID +「-chk」'會立即得到評估,因此,這將實際上工作,雖然醜陋...但是,當然'ID'的價值會有同樣的問題。 – 2013-02-22 07:41:03

回答

3

您需要在循環的每次迭代中捕獲i的值。您可以通過引入新的範圍與立即調用的函數表達式做到這一點:

for(var i = 0; i < idList.length; i++) { 
    (function (i) { 
     $(document).on("change", "#dropdown-menu-"+idList[i]+"-chk", function() { 
      // etc... 
     }); 
    }(i)); 
} 
+0

我該讀什麼聲明?我知道它在想什麼。這是一個匿名函數還是什麼? – 2013-02-22 07:40:37

+0

@AlanDert - 是的,這是一個匿名函數,立即執行。你會經常聽到這被稱爲封閉。這引入了一個新的範圍,該範圍在其創建時保持對外部詞彙環境的引用。這意味着匿名函數在創建時總是可以訪問'i'的狀態。 – 2013-02-22 07:43:05

+0

爲什麼在我的情況下有懶惰的行爲? – 2013-02-25 09:03:23