2013-06-05 27 views
0

我正在添加一個事件監聽器給我循環的一些元素,並且需要一個閉包來保存事件函數中的索引。在for循環中正確使用閉包?

<button>solution 1</button> 
<button>solution 2</button> 

<script> 
var buttons = document.getElementsByTagName('button'); 
for (var i = 0; i < 3; i++) { 
    var log = (function closure(number) { 
     return function() { 
      console.log(number); 
     }; 
    })(i); 

    buttons[0].addEventListener("click", log); 
} 
for (var i = 0, len = 3; i < len; i++) { 
    (function (i) { 
     var log = function() { 
       console.log(i); 
      }; 
     buttons[1].addEventListener("click", log); 
    })(i); 
} 
</script> 

http://jsfiddle.net/paptd/11/

這兩種解決方案輸出0,1,2正確(試行「錯」看到沒有關閉會發生什麼),但我想了解哪一個我應該使用以及爲什麼。

哪種方式是正確的做法?

+0

聽衆有幾百相反的,你可以使用事件代表團。它將佔用更少的內存,並且您將在代碼和DOM之間的聯繫更少。 您只需要一個事件偵聽器。例如:http://nczonline.net/blog/2009/06/30/event-delegation-in-javascript –

回答

1

第一個工作原因是您定義了一個閉包,從中返回一個函數,然後將該函數分配給一個偵聽器。

第二個看起來更合適,因爲閉包涵蓋了整個循環內容,更明顯的是i的值將被「鎖定」在那裏。

1

你不應該使用任何這些 - 你正在創建n你的循環內部的相同函數。你應該重構你的代碼到一個名爲的函數,返回事件處理程序:

var buttons = document.getElementsByTagName('button'); 

function createHandler(number) { 
    return function() { 
     console.log(number); 
    }; 
} 

for (var i = 0; i < 3; i++) { 
    buttons[0].addEventListener("click", createHandler(i)); 
} 

例子:http://jsfiddle.net/paptd/12/