話不多說了。
先來看兩段代碼:
var elems = document.getElementsByTagName('a');for (var i = 0; i < elems.length; i++) {alert(i); elems[i].addEventListener('click', function (e) { e.preventDefault(); alert('I am link #' + i); }, 'false');}
再看一面一段:
var elems = document.getElementsByTagName('a');for (var i = 0; i < elems.length; i++) {(function(index){ elems[i].addEventListener('click', function (e) {e.preventDefault();alert('I am link #' + index);}, 'false');})(i);}
HTML 程式碼如下:
<body><a href = "#">a</a><a href = "#">a</a><a href = "#">a</a><a href = "#">a</a><a href = "#">a</a><a href = "#">a</a><a href = "#">a</a><a href = "#">a</a></body>
你可以想像下,前後兩段 script代碼的效果。
如果你能看出來效果的區別,那麼恭喜你。至少我思考了很久,才明白裡面的玄妙。
是的。你沒有看錯,這裡的第一段代碼,無論你點擊哪一個連結,輸出的都是 I am link # 8.
第二段代碼,才是你真正想要的結果,那麼為什麼呢。
看下面的代碼:
var elems = document.getElementsByTagName('a');for (var i = 0; i < elems.length; i++) {alert(i); elems[i].addEventListener('click', function (e) { e.preventDefault(); alert('I am link #' + i);//注意這裡的回呼函數只有的觸發的時候才會啟動//一樣,這裡的i的值也一樣在迴圈結束的時候也變化了 }, 'false');//原因在於//這裡的elems[i] 雖然是引用的元素 //但是回呼函數中的i 已經在迴圈結束後//變成了8(如果 elems 的長度是 8 的話)}
var elems = document.getElementsByTagName('a');for (var i = 0; i < elems.length; i++) {(function(index){ elems[i].addEventListener('click', function (e) {e.preventDefault();alert('I am link #' + index);}, 'false');})(i); //而這裡的則不一樣 //雖然迴圈結束後i 的值變成了8 //但是在封裝在閉包內的index 確實一直被locked 住的 //一直儲存在記憶體中。 //準確的說 應該是整個函數都lock在記憶體中.}
這裡可能需要一些javascript閉包的知識。
以上代碼,想了很久,記錄下來,以防止忘記。