for(var i = 0;i<3;i++){ setTimeout(function(){ console.log(i) },1000) };
打印結果:三個3
原因分析:setTimeout()是一個異步處理函數,它會等待所有的主線程任務處理完,才開始執行自己的內部的任務,每隔1s往任務隊列中添加一個任務【閉包函數,setTimeout()中的函數,現在還沒執行】,當主線程執行完時,這時i=3,
才開始執行任務隊列中的任務【閉包函數,setTimeout()中的函數開始執行,執行三次】。
for循環是遵循js執行機制--從上到下,依次同步執行,for循環括號內的就是主線程,執行完時i是3,所以會打印出3次3;
如果想打印出0,1,2
解決方案:
- 把var改為let,let是塊極作用域,每次for循環都會把對應的i綁定到添加的任務【閉包函數,setTimeout()中的函數】中,所以當主線程執行完時,也不會影響到每個任務中i。所以可以打印出0 1 2
- 把定時器放在一個自執行函數中用i當做參數
(function(i){ setTimeout(function(){ console.log(i); },1000) })(i)