1. 程式人生 > >js中for迴圈內的匿名函式使用i的問題及解決方案

js中for迴圈內的匿名函式使用i的問題及解決方案

問題描述

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