js中for迴圈內的匿名函式使用i的問題及解決方案
阿新 • • 發佈:2018-12-17
問題描述
js中由於作用域鏈及js執行機制導致的for迴圈中匿名函式使用i的問題
<!--現有html結構程式碼如下-->
<ul>
<li>VueJs</li>
<li>AngularJs</li>
<li>ReactJs</li>
<li>NodeJs</li>
</ul>
// 執行如下程式碼
var liobjs=document.getElementsByTagName('li');
for(var i=0;i<liobjs.length;i++ ){
liobjs[i].onclick=function(){
console.log(i)
}
}
無論點選哪個li,輸出的 i 值都為: 4
分析
在onclick事件處理函式中,該作用域內沒有 i 變數,因此會沿著作用域鏈往父類中尋找 i,而在for迴圈中有變數i值,因此事件處理函式中會使用該變數。可是!!由於for迴圈是同步任務,頁面載入完畢後,for迴圈瞬間就執行完畢了,i 瞬間就變成 4了,在為每個 li 註冊好點選事件(非同步任務)後,每次點選時,彈出的值都是4
解決方案一
//
var liobjs=document.getElementsByTagName ('li');
for(var i=0;i<liobjs.length;i++){
(function(i){
liobjs[i].onclick=function(){
console.log(i)
}
})(i)
}
使用自執行函式,並將i作為引數傳入,此時 i 從全域性變數變為區域性變數 依次點選 li 輸出:0 1 2 3
解決方案二
for(let i = 0;i<liobjs.length;i++){
liobjs[i].onclick =function () {
console.log(i);
}
}
使用 let 定義變數 i 依次點選 li 輸出: 0 1 2 3