打臉了,這并不是閉包的問題,而是一個事件循環(huán)機制
以下為錯誤解釋
這是一個關于變量閉包的問題英遭,以前做項目時遇到,那時候并沒有想明白亦渗,換了另一種方法實現(xiàn)挖诸,今天看閉包的知識點時恍然大悟,于是法精,寫出來記錄下多律。
首先,主要涉及兩個概念
變量的作用域:也就是變量的有效范圍搂蜓,函數(shù)內部變量的作用域也就只能在函數(shù)內部使用狼荞。
變量的生存周期:對于函數(shù)的局部變量,函數(shù)退出后也就失去了價值帮碰,他們也會隨著函數(shù)調用的結束而銷毀相味。
然后,上閉包應用殉挽。
假設頁面上有5個div節(jié)點丰涉,我們通過循環(huán)來給每個div綁定onclick事件拓巧,按照索引順序,點擊第1個div時彈出0昔搂,點擊第2個div時彈出1玲销,以此類推。如果用常規(guī)的綁定就會出現(xiàn)題目中的問題摘符。
原因:div節(jié)點的onclick事件是被異步觸發(fā)的贤斜,當事件被觸發(fā)的時候,for循環(huán)早已結束逛裤,此時變量i的值已經是5瘩绒,所以在div的onclick事件函數(shù)中順著作用域鏈從內到外查找變量i時,查找到的值總是5(注釋部分代碼可以嘗試一下)带族。
解決辦法:在閉包的幫助下锁荔,把每次循環(huán)的i值都封閉起來。當在事件函數(shù)中順著作用域鏈中從內到外查找變量i時蝙砌,會先找到被封閉在閉包環(huán)境中的i阳堕,如果有5個div,這里的i就分別是0,1,2,3,4:
最后择克,上代碼恬总,結合以上解釋。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>閉包</title>
</head>
<style type="text/css">
div {
width: 100%;
height: 50px;
margin: 20px 0;
border: aqua 1px solid;
background: #00FFFF;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
div:hover {
background: chartreuse;
}
</style>
<body>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</body>
<script type="text/javascript">
var nodes = document.getElementsByTagName('div');
/* 未使用閉包前 */
// for(var i=0,len=nodes.length; i<len; i++) {
// nodes[i].onclick = function() {
// alert(i);
// }
// }
for(var i=0,len=nodes.length; i<len; i++) {
(function(i){
nodes[i].onclick = function() {
alert(i);
}
})(i)
}
</script>
</html>
效果截圖:
image.png
image.png