国产成在线人视频免费视频-国产成综合-国产床上视频-国产大臿蕉香蕉大视频女-国产大尺度pr社18福利在线

你不知道的JavaScript:有趣的setTimeout

2018-5-7    周周

     話不多說,先上代碼

     for(var j=0;j<10;J++){

         setTimeout(function(){console.log(j);},5000)

     }

     看到這三行代碼,你也許會不耐煩道:又要講閉包?要吐槽了好么?別急,讓我們先來思考一下,這段代碼在瀏覽器中的執(zhí)行結果是什么?

     <!-- more -->

     甲:順序打印0到9?

     乙:這題我見過,打印十個10!

     哪個答案正確?

     執(zhí)行結果顯示,瀏覽器打印出十個10,貌似乙對了,但是如果你足夠細心,你會發(fā)現(xiàn)幾個問題:為什么會循環(huán)打印十個10,而不是0到9?

     從結果來看,for循環(huán)執(zhí)行完跳出之后,才開始執(zhí)行setTimeout(所以j才等于10),為什么不是每次迭代都執(zhí)行一次setTimeout呢?

1、為什么會循環(huán)打印十個10?

      許多人習慣用第二個問題中的執(zhí)行結果來回答這個問題:“for循環(huán)執(zhí)行完畢跳出之后才開始執(zhí)行setTimeout,所以才打印了十個10”。這樣的答案,只能說是既應付了自己,又應付了別人。其實,要解答第一個問題,首先要解答第二個問題。

2、為什么不是每一次迭代都執(zhí)行一次setTimeout?

     大家都知道,JavaScript在ES6出現(xiàn)以前,是沒有塊狀作用域的,這就意味著,在for循環(huán)中用var定義的變量j,其實是屬于全局的,那其實整個全局作用域中只有一個j,每次for循環(huán)都是更新這個j。

       那么現(xiàn)在的關鍵問題在于,為什么整個for循環(huán)會先于setTimeout執(zhí)行,而不是我們正常理解的,一次迭代執(zhí)行一次。這就涉及到了JavaScript的核心特性:單線程。

       JavaScript設計的初衷,是瀏覽器用來與用戶進行交互和DOM操作的,這就決定了它必須是單線程的。設想JavaScript同時有兩個線程,一個線程在DOM節(jié)點內添加內容,一個線程刪除該節(jié)點,瀏覽器就會出現(xiàn)混亂。所以,為了避免復雜性,從一誕生,JavaScript就是單線程,這已經成為了這門語言的核心特征,將來也不會改變。

      單線程就意味著,所有任務需要排隊,前一個任務結束,才會執(zhí)行下一個任務,如果前一個任務耗時很長,后一個任務就不得不一直等著。

      為了優(yōu)化單線程的性能,JavaScript將任務分成兩種,一種是同步任務(synchronous),另一種是異步任務(asynchronous)。同步任務指的是,在主線程上排隊執(zhí)行的任務,只有前一個任務執(zhí)行完畢,才能執(zhí)行后一個任務;異步任務指的是,不進入主線程,而進入“任務隊列(task queue)”的任務,只用主線程中的同步任務執(zhí)行完畢,異步任務才會進入執(zhí)行隊列執(zhí)行。只要主線程空了,就會去讀取“任務隊列”,這就是JavaScript的運作機制。這個過程會不斷重復。

       而setTimeout就被JavaScript定義為異步任務。每次for循環(huán)的迭代,都將setTimeout中的回調函數(shù)加入任務隊列等待執(zhí)行。也就是說,只有同步任務中的for循環(huán)完全結束,主線程中才會去任務列表中找到尚未執(zhí)行的十個setTimeout(十次迭代)回調函數(shù)并順序執(zhí)行(先進先出)。而此時,j已經經過循環(huán)結束變成了10,所以此時主線程執(zhí)行的,是十個一模一樣的打印i的回調函數(shù),即打印十個10,。至此完美回答了第一和第二個問題,文章開頭的代碼與下面的代碼其實是等價的:

       for(var i=0;i<10;i++){

            setTimeout(console.log(i),5000);

            setTimeout(console.log(i),5000);

            setTimeout(console.log(i),5000);

            setTimeout(console.log(i),5000);

            setTimeout(console.log(i),5000);

            setTimeout(console.log(i),5000);

            setTimeout(console.log(i),5000);

            setTimeout(console.log(i),5000);

            setTimeout(console.log(i),5000);

            setTimeout(console.log(i),5000);

}

       小小的一個setTimeout,牽扯出了很多JavaScript的深層次問題,可見JavaScript還有許多地方是值得深入探究的。



日歷

鏈接

個人資料

藍藍設計的小編 http://www.z1277.cn

存檔

主站蜘蛛池模板: 精品久久久久久国产免费了 | 久热在线播放中文字幕 | 欧美另类老人xxxx | 国产在线观看网站 | 亚洲免费影院 | 欧洲欧美人成免费观看 | 国产精品一区二区欧美视频 | 亚洲香蕉毛片久久网站老妇人 | 51精品视频免费国产专区 | 妞干网在线视频观看 | 国产精品久久久久久小说 | 在线香蕉 | 亚洲一区二区三区四区视频 | 欧美xxxx狂喷水喷水 | 自拍偷拍国语对白 | 亚洲精品国产经典一区二区 | 国产真实乱freesex | 在线观看国产免费高清不卡 | 柠檬福利视频在线观看 | 91久久亚洲精品一区二区 | 亚洲视频综合 | 亚洲视频网址 | 香港毛片免费观看 | 国产黄色片在线观看 | 亚洲黄色片子 | 亚洲精品亚洲人成在线观看麻豆 | 精品二区 | 成年女美黄网站大全免费播放 | 免费看国产精品麻豆 | 日本三级免费 | 欧美一级二级三级视频 | 看黄网址在线观看 | 黄色片网站在线免费观看 | 欧美日韩一二三四区 | 成人午夜影视全部免费看 | 亚洲狠狠ady亚洲精品大秀 | 黄+色+性+人免费 | 亚洲 日本 欧美 日韩精品 | 亚洲性色综合图区图片 | 网址在线 | 看草逼 |