1. 程式人生 > >JS之經典for循環閉包問題解決方法

JS之經典for循環閉包問題解決方法

AI ref length 代碼片段 inf char for循環 AS row

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="bootstrap.css">

</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-3">
<hr>
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">閉包經典實例</h3>
<div>
<div class="panel-body">
<ul class="list-group">
<li class="list-group-item">1</li>
<li class="list-group-item">2</li>
<li class="list-group-item">3</li>
<li class="list-group-item">4</li>
<li class="list-group-item">5</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script >
var liList=document.getElementsByTagName(‘li‘);

for(var i=0;i<liList.length;i++){

liList[i].number=i;
liList[i].onclick=function(){
alert(this.number)
}

// (function (i){
// liList[i].onclick=function( ){
// alert(‘當前點擊第‘+ i+‘個‘);
// }
// })(i)
}
</script>
</body>
</html>


像這樣一個代碼片段,初學者會理所當然地認為依次點擊Li會彈出相應的0、1、2、3、4 但實際結果是每次都是4
原因是:每次點擊輸出i的時候,函數內部沒有i,就從外部函數查找,而外部函數的值是每一次循環後的值4,所以每次點擊輸出的都是4

解決辦法一:加一層閉包,i 以函數參數形式傳遞給內層函數:

          (function (i){
liList[i].onclick=function( ){
alert(‘當前點擊第‘+ i+‘個‘);
}
})(i)

解決辦法二:找個屬性將i值保存起來,然後彈出這個值

        liList[i].number=i;
liList[i].onclick=function(){
alert(this.number)
}


JS之經典for循環閉包問題解決方法