成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

圖例詳解那道setTimeout與循環閉包的經典面試題

開發 前端
值得高興的是很多朋友在讀了文章之后確實對閉包有了更加深刻的了解,并準確的給出了幾種寫法。但是也有一些基礎稍差的朋友在閱讀了之后,對于這題的理解仍然感到困惑,因此應一些讀者老爺的要求,借此文章專門對setTimeout進行一個相關的知識分享,愿大家讀完之后都能夠有新的收獲。

[[208795]]

我在詳細圖解作用域鏈與閉包一文中的結尾留下了一個關于setTimeout與循環閉包的思考題。

利用閉包,修改下面的代碼,讓循環輸出的結果依次為1, 2, 3, 4, 5

  1. for (var i=1; i<=5; i++) { 
  2.     setTimeout( function timer() { 
  3.         console.log(i); 
  4.     }, i*1000 ); 
  5.  

值得高興的是很多朋友在讀了文章之后確實對閉包有了更加深刻的了解,并準確的給出了幾種寫法。一些朋友能夠認真的閱讀我的文章并且一個例子一個例子的上手練習,這種認可對我而言真的非常感動。但是也有一些基礎稍差的朋友在閱讀了之后,對于這題的理解仍然感到困惑,因此應一些讀者老爺的要求,借此文章專門對setTimeout進行一個相關的知識分享,愿大家讀完之后都能夠有新的收獲。

在最初學習setTimeout的時候,我們很容易知道setTimeout有兩個參數,***個參數為一個函數,我們通過該函數定義將要執行的操作。第二個參數為一個時間毫秒數,表示延遲執行的時間。

  1. setTimeout(function() { 
  2.     console.log('一秒鐘之后我將被打印出來'
  3. }, 1000)  

 

上例執行結果

可能不少人對于setTimeout的理解止步于此,但還是有不少人發現了一些其他的東西,并在評論里提出了疑問。比如上圖中的這個數字7,是什么?

每一個setTimeout在執行時,會返回一個***ID,上圖中的數字7,就是這個***ID。我們在使用時,常常會使用一個變量將這個***ID保存起來,用以傳入clearTimeout,清除定時器。

  1. var timer = setTimeout(function() { 
  2.  
  3. console.log('如果不清除我,我將會一秒之后出現。'); 
  4.  
  5. }, 1000) 
  6.  
  7. clearTimeout(timer); // 清除之后,通過setTimeout定義的操作并不會執行  

接下來,我們還需要考慮另外一個重要的問題,那就是setTimeout中定義的操作,在什么時候執行?為了引起大家的重視,我們來看看下面的例子。

  1. var timer = setTimeout(function() { 
  2.  
  3. console.log('setTimeout actions.'); 
  4.  
  5. }, 0); 
  6.  
  7. console.log('other actions.'); 
  8.  
  9. // 思考一下,當我將setTimeout的延遲時間設置為0時,上面的執行順序會是什么?  

在瀏覽器中的console中運行試試看,很容易就能夠知道答案,如果你沒有猜中答案,那么我這篇文章就值得你點一個贊了,因為接下來我分享的小知識,可能會在筆試中救你一命。

在對于執行上下文的介紹中,我與大家分享了函數調用棧這種特殊數據結構的調用特性。在這里,將會介紹另外一個特殊的隊列結構,頁面中所有由setTimeout定義的操作,都將放在同一個隊列中依次執行。

我用下圖跟大家展示一下隊列數據結構的特點。

 

隊列:先進先出

而這個隊列執行的時間,需要等待到函數調用棧清空之后才開始執行。即所有可執行代碼執行完畢之后,才會開始執行由setTimeout定義的操作。而這些操作進入隊列的順序,則由設定的延遲時間來決定。

因此在上面這個例子中,即使我們將延遲時間設置為0,它定義的操作仍然需要等待所有代碼執行完畢之后才開始執行。這里的延遲時間,并非相對于setTimeout執行這一刻,而是相對于其他代碼執行完畢這一刻。所以上面的例子執行結果就非常容易理解了。

為了幫助大家理解,再來一個結合變量提升的更加復雜的例子。如果你能夠正確看出執行順序,那么你對于函數的執行就有了比較正確的認識了,如果還不能,就回過頭去看看其他幾篇文章。

  1. setTimeout(function() { 
  2.     console.log(a); 
  3. }, 0); 
  4.   
  5. var a = 10; 
  6.   
  7. console.log(b); 
  8. console.log(fn); 
  9.   
  10. var b = 20; 
  11.   
  12. function fn() { 
  13.     setTimeout(function() { 
  14.         console.log('setTImeout 10ms.'); 
  15.     }, 10); 
  16.   
  17. fn.toString = function() { 
  18.     return 30; 
  19.   
  20. console.log(fn); 
  21.   
  22. setTimeout(function() { 
  23.     console.log('setTimeout 20ms.'); 
  24. }, 20); 
  25.   
  26. fn();  

上栗執行結果

OK,關于setTimeout就暫時先介紹到這里,我們回過頭來看看那個循環閉包的思考題。

  1. for (var i=1; i<=5; i++) { 
  2.     setTimeout( function timer() { 
  3.         console.log(i); 
  4.     }, i*1000 ); 
  5.  

如果我們直接這樣寫,根據setTimeout定義的操作在函數調用棧清空之后才會執行的特點,for循環里定義了5個setTimeout操作。而當這些操作開始執行時,for循環的i值,已經先一步變成了6。因此輸出結果總為6。而我們想要讓輸出結果依次執行,我們就必須借助閉包的特性,每次循環時,將i值保存在一個閉包中,當setTimeout中定義的操作執行時,則訪問對應閉包保存的i值即可。

而我們知道在函數中閉包判定的準則,即執行時是否在內部定義的函數中訪問了上層作用域的變量。因此我們需要包裹一層自執行函數為閉包的形成提供條件。

因此,我們只需要2個操作就可以完成題目需求,一是使用自執行函數提供閉包條件,二是傳入i值并保存在閉包中。

  1. for (var i=1; i<=5; i++) { 
  2.   
  3.     (function(i) { 
  4.         setTimeout( function timer() { 
  5.             console.log(i); 
  6.         }, i*1000 ); 
  7.     })(i) 
  8.  

 

利用斷點調試,在chrome中查看執行順序與每一個閉包中不同的i值

當然,也可以在setTimeout的***個參數處利用閉包。

  1. for (var i=1; i<=5; i++) {  
  2.    setTimeout( (function(i) { 
  3.         return function() { 
  4.             console.log(i); 
  5.         } 
  6.     })(i), i*1000 ); 
  7.  
責任編輯:龐桂玉 來源: 前端大全
相關推薦

2024-04-15 08:34:43

2024-04-28 08:23:18

2021-03-01 09:39:34

閉包JavaScript開發

2015-11-25 10:48:44

JS閉包面試題

2021-10-26 11:45:22

Vue面試前端

2011-06-14 09:12:03

JavaScript

2024-04-09 08:32:58

Java面試題線程

2010-11-26 10:53:29

戴爾

2024-06-04 14:52:28

2024-04-07 08:23:49

Java面試題集合框架

2014-07-28 14:00:40

linux面試題

2017-12-14 08:04:21

Java面試程序

2025-05-29 08:10:00

Linux進程系統

2022-06-27 09:14:34

JavaScript閉包代碼

2024-10-11 17:09:27

2020-11-13 16:00:57

SpringCloud面試架構

2023-11-09 16:13:00

TypeScript前端

2024-02-26 15:35:44

2024-01-01 15:30:59

JavaScriptWeb 應用程序開發

2023-09-21 14:55:24

Web 開發TypeScript
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲国产精品成人综合久久久 | 视频一区欧美 | 1级黄色大片 | 成人免费在线视频 | 国产一二区视频 | 五月婷婷激情 | www.日韩高清 | 日韩毛片在线视频 | 网站黄色在线免费观看 | 成年人黄色小视频 | 亚洲一二三在线 | 精品福利一区二区三区 | 欧美一区视频 | 一区二区三区欧美大片 | 91欧美精品成人综合在线观看 | 国产线视频精品免费观看视频 | 欧美日韩在线免费观看 | 久久曰视频 | 色精品视频 | 成人在线观看亚洲 | 中文字幕高清一区 | 欧美激情一区 | 久久久久精 | 日韩精品在线观看免费 | 欧美性极品xxxx做受 | 国产一区二区久久 | 亚洲午夜视频在线观看 | 久久艹免费视频 | 国产一区91精品张津瑜 | 中文字幕久久久 | 一区二区三区免费看 | 99这里只有精品视频 | 日韩在线免费视频 | 亚洲www啪成人一区二区 | 91porn国产成人福利 | 国产精品日韩欧美 | 一区二区三区在线播放视频 | 正在播放国产精品 | 久久国产精品免费 | 欧美男人天堂 | 一级毛片在线播放 |