for(var i=0;i<=3;i++){ setTimeout(function() { console.log(i) }, 10);}


for(var i=0;i<=3;i++){ setTimeout(function() {  console.log(i)  }, 10);}

答案:打印4次4

這道題涉及了異步、作用域、閉包

settimeout是異步執行,10ms后往任務隊列里面添加一個任務,只有主線上的全部執行完,才會執行任務隊列里的任務,當主線執行完成后,i是4,所以此時再去執行任務隊列里的任務時,i全部是4了。對於打印4次是:

 每一次for循環的時候,settimeout都執行一次,但是里面的函數沒有被執行,而是被放到了任務隊列里面,等待執行,for循環了4次,就放了4次,當主線程執行完成后,才進入任務隊列里面執行。
   (注意:for循環從開始到結束的過程,需要維持幾微秒或幾毫秒。)
當我把var 變成let 時
for(let i=0;i<=3;i++){ setTimeout(function() {  console.log(i)  }, 10);}
打印出的是:0,1,2,3
當解決變量作用域,

因為for循環頭部的let不僅將i綁定到for循環快中,事實上它將其重新綁定到循環體的每一次迭代中,確保上一次迭代結束的值重新被賦值。setTimeout里面的function()屬於一個新的域,通過 var 定義的變量是無法傳入到這個函數執行域中的,通過使用 let 來聲明塊變量,這時候變量就能作用於這個塊,所以 function就能使用 i 這個變量了;這個匿名函數的參數作用域 和 for參數的作用域 不一樣,是利用了這一點來完成的。這個匿名函數的作用域有點類似類的屬性,是可以被內層方法使用的。

查了一下百度的一個答案:

setTimeout是一次執行函數,這里是10ms后執行,僅僅執行一次;for(var i=0;i<=3;i++),i的每次取值都是執行setTimeout這個函數,並沒有執行setTimeout里面的function(即閉包函數),setTimeout里面的function是有setTimeout的定時觸動的,也就是10ms后執行,也就是說i從0~3時,一共執行了4次的setTimeout()函數,此時的i的值是4,由於for語句的執行速度遠小於1秒,所以,1秒后,由setTimeout()函數定時觸動的閉包函數function()開始執行,alert(i);i的值已經是4了,所以相繼打印4次i.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM