簡體   English   中英

循環中的JavaScript函數

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM