[英]JavaScript Function inside the loop
有人可以向我解釋為什么JSLint在這個例子中抱怨“循環中的函數”:
for (var i = 0; i < buttons.length; i++) {
(function(i) {
buttons[i].onclick = function(e) {
t.progressBars[t.current].update(buttons[i].getAttribute("data-value"));
}
})(i);
}
但是,當我把它改為:
function makeHandler(i)
{
return function() {
t.progressBars[t.current].update(buttons[i].getAttribute("data-value"));
}
}
for (var i = 0; i < buttons.length; i++) {
buttons[i].onclick = makeHandler(i);
}
我不太明白,因為似乎每次循環迭代都必須返回新的函數對象,即使它發生在makeHandler()
函數內部。 為什么第二個例子適用於JS短片?
引用linterrors ,
var elems = document.getElementsByClassName("myClass"), i; for (i = 0; i < elems.length; i++) { (function (iCopy) { "use strict"; elems[i].addEventListener("click", function () { this.innerHTML = iCopy; }); }(i)); }
我們現在在循環的每次迭代中捕獲
i
的值。 發生這種情況是因為JavaScript通過值將參數傳遞給函數。 這意味着捕獲函數中的iCopy
與i無任何關系(除非它們恰好在該時間點具有相同的值)。 如果i
稍后改變(它會在循環的下一次迭代中改變),那么iCopy
不會受到影響。這將按照我們的預期工作,但現在的問題是JavaScript解釋器將在每次循環迭代中創建捕獲函數的實例。 它必須這樣做,因為它不知道函數對象是否會在別處修改。 由於函數是標准JavaScript對象,因此它們可以具有與任何其他對象相同的屬性,這些屬性可以在循環中更改。 因此,通過在循環上下文中創建函數,可以使解釋器創建多個函數實例,這可能會導致意外行為和性能問題。 要解決這個問題,我們需要將該函數移出循環:
我本來希望在這里使用Array.prototype.forEach
,就像這樣
buttons.forEach(function(curButton) {
curButton.onclick = function(e) {
t.progressBars[t.current].update(curButton.getAttribute("data-value"));
};
});
你的兩個例子並不等同。
在第一個中,您將創建一個匿名函數並在每個循環上調用它。
內部函數(單擊事件處理程序)很好 - 您正在分配一個新函數 - 但它是在此上下文中效率低下的匿名外部函數。 在你的第二個例子中,外部函數被重構出來,它只創建一次,而不是buttons.length
次。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.