錯誤寫法for(vari=0;i
JavaScript循環(huán)內的閉包為什么返回的是最后一個值
狐的傳說
2019-04-14 10:21:29
TA貢獻1876條經驗 獲得超5個贊
//每次循環(huán)會調用setTimeout函數,其中指定了一個timeout后執(zhí)行的函數//這個函數因為構成閉包的關系,其能夠訪問外層函數定義的變量,這個變量就是i//在for循環(huán)執(zhí)行完畢后,i的值為10.此時在事件隊列中有10個timeout函數等待執(zhí)行//當timeout時間到時,對應的執(zhí)行函數調用的i都是同一個,也就是10for(vari=0;i<10;i++){setTimeout(function(){console.log(i);},1000);}//在for循環(huán)中定義了匿名立即執(zhí)行函數//通過將每次循環(huán)時產生i傳入匿名立即執(zhí)行函數,立即執(zhí)行函數就有了一個內部變量e,//其值是傳入的i//setTimeout函數形成閉包,能訪問到其外層函數也就是匿名立即執(zhí)行函數的變量e//因為e引用關系的存在,匿名立即執(zhí)行函數不會被馬上銷毀掉//timeout時間一到,指定執(zhí)行函數調用的e就是每次傳入的參數ifor(vari=0;i<10;i++){(function(e){setTimeout(function(){console.log(e);},1000);})(i);}//整個和上面的類似,只不過把匿名立即執(zhí)行函數傳遞給setTimeout的第1個參數中//匿名立即執(zhí)行函數,顧名思義就是需要立即執(zhí)行的呀。//所以setTimout函數對應的超時執(zhí)行函數(第1個參數)//為匿名立即執(zhí)行函數執(zhí)行的結果,也就是返回的函數。//接下來理解就和上面一樣啦for(vari=0;i<10;i++){setTimeout((function(e){returnfunction(){console.log(e);}})(i),1000)}
TA貢獻1847條經驗 獲得超11個贊
因為ES6之前沒有塊作用域for(vari=0;i<10;++i){setTimeout(function(){console.log(i)},1000)}有塊作用域時效果如同for(vari=0;i<10;++i){varj=0j=isetTimeout(function(){console.log(j)},1000)}就是塊內代碼引用的i變量均不是指向同一個變量。而ES6則引入let關鍵字來標識變量位于塊作用域內for(leti=0;i<10;++i){setTimeout(function(){console.log(i)},1000)}當然在ES3/5下除了通過IIFE構造作用域外,還可以通過with來構造for(vari=0;i<10;++i)with({i:i}){setTimeout(function(){console.log(i)},1000)}
舉報