• <center id="sm46c"></center>
  • <dfn id="sm46c"></dfn>
  • <strike id="sm46c"></strike>
  • <cite id="sm46c"><source id="sm46c"></source></cite>
    • <strike id="sm46c"><source id="sm46c"></source></strike>
      <option id="sm46c"></option>
      国产精品天天看天天狠,女高中生强奷系列在线播放,久久无码免费的a毛片大全,国产日韩综合av在线,亚洲国产中文综合专区在,特殊重囗味sm在线观看无码,中文字幕一区二区三区四区在线,无码任你躁久久久久久老妇蜜桃

      你不知道的JavaScript:有趣的setTimeout

      2018-5-7    高勁

           話不多說,先上代碼

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

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

           }

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

           <!-- more -->

           甲:順序打印0到9?

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

           哪個答案正確?

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

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

      1、為什么會循環打印十個10?

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

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

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

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

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

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

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

             而setTimeout就被JavaScript定義為異步任務。每次for循環的迭代,都將setTimeout中的回調函數加入任務隊列等待執行。也就是說,只有同步任務中的for循環完全結束,主線程中才會去任務列表中找到尚未執行的十個setTimeout(十次迭代)回調函數并順序執行(先進先出)。而此時,j已經經過循環結束變成了10,所以此時主線程執行的,是十個一模一樣的打印i的回調函數,即打印十個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.li-bodun.cn

      存檔

      主站蜘蛛池模板: 国产精品偷乱一区二区三区| 狠狠色丁香久久婷婷综合五月| 亚洲综合第一区| 中文字幕v亚洲日本在线电影| 色吊a中文字幕一二三区| 色丁狠狠桃花久久综合网| 亚洲国产综合自在线另类| 久久精品国产亚洲av麻豆不卡| 久久夜色噜噜噜亚洲av| 亚洲人成日本在线观看| 无码纯肉视频在线观看| 亚洲AV无一区二区三区| 亚洲国产福利一区二区三区| 精品无码一区二区三区在线| 影音先锋女人aa鲁色资源| 久草国产视频| 天堂av无码大芭蕉伊人av孕妇 | 亚洲高清 一区二区三区| 亚洲日韩av无码中文字幕美国| 国产国产人免费人成免费| 国产精品久久久久久久久ktv| 欧妇女乱妇女乱视频| 日本手机在线| 免费不卡人妻无码中出| 色综合色综合色综合频道| 中文字幕乱码亚洲无线精品一区| 少妇尿尿一区二区在线免费| 久热中文字幕在线观看| 色翁荡熄又大又硬又粗又视频| 亚洲精品国产免费无码网站| 四虎成人精品国产永久免费无码| 欧美精品影院| 无码精品a∨在线观看十八禁| 国精产品自偷自偷综合下载| 26uuu另类亚洲欧美日本| 免费国产va在线观看视频| 99热线精品大全在线观看| 久久月本道色综合久久| 先锋资源久久| 国产内射一区亚洲| 日本高清中文字幕一区二区三区|