欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

for循環(huán) + setTimeout 結(jié)合一些示例(前端面試題)

 更新時(shí)間:2017年08月30日 14:18:34   作者:小蔣不素小蔣  
最近在學(xué)習(xí)node.js開發(fā)資料,正好碰到了for循環(huán)+settimeout的經(jīng)典例子,下面小編給大家分享for循環(huán) + setTimeout 結(jié)合一些示例代碼,需要的朋友參考下吧

一、背景

最近在翻看以前的老書《node.js開發(fā)指南》,恰好碰到 for 循環(huán) + setTimeout 的經(jīng)典例子,于是重新梳理了思路并記錄下。

二、寫在前面,setTimeout 和 setInterval 的執(zhí)行機(jī)制

在日常編碼中,你會(huì)發(fā)現(xiàn),給 setTimeout 和 setInterval 設(shè)定延遲時(shí)間往往并不準(zhǔn),或者干脆 setTimeout(function(){xxx},0) 也不是立馬執(zhí)行(特別是有耗時(shí)代碼在前),這是因?yàn)?js 是單線程的,有一個(gè)事件隊(duì)列機(jī)制,setTimeout 和 setInterval 的回調(diào)會(huì)到了延遲時(shí)間塞入事件隊(duì)列中,排隊(duì)執(zhí)行。

setTimeout :延時(shí) delay 毫秒之后,啥也不管,直接將回調(diào)函數(shù)加入事件隊(duì)列。

setInterval :延時(shí) delay 毫秒之后,先看看事件隊(duì)列中是否存在還沒(méi)有執(zhí)行的回調(diào)函數(shù)( setInterval 的回調(diào)函數(shù)),如果存在,就不要再往事件隊(duì)列里加入回調(diào)函數(shù)了。

看下面示例:

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

結(jié)果:1 秒之后,同時(shí)輸出 5 個(gè) 5。

因?yàn)?for 循環(huán)會(huì)先執(zhí)行完(同步優(yōu)先于異步優(yōu)先于回調(diào)),這時(shí)五個(gè) setTimeout 的回調(diào)全部塞入了事件隊(duì)列中,然后 1 秒后一起執(zhí)行了。

三、正文

接下來(lái)就是那道經(jīng)典的代碼:

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

結(jié)果:5 5 5 5 5

為什么不是 1 2 3 4 5,問(wèn)題出在作用域上。

因?yàn)?setTimeout 的 console.log(i); 的i是 var 定義的,所以是函數(shù)級(jí)的作用域,不屬于 for 循環(huán)體,屬于 global。等到 for 循環(huán)結(jié)束,i 已經(jīng)等于 5 了,這個(gè)時(shí)候再執(zhí)行 setTimeout 的五個(gè)回調(diào)函數(shù)(參考上面對(duì)事件機(jī)制的闡述),里面的 console.log(i); 的 i 去向上找作用域,只能找到 global下 的 i,即 5。所以輸出都是 5。

解決辦法:人為給 console.log(i); 創(chuàng)造作用域,保存i的值。

解決辦法一

for (var i = 0; i < 5; i++) { 
  (function(i){   //立刻執(zhí)行函數(shù)
    setTimeout(function (){
      console.log(i); 
     },1000); 
  })(i); 
}

這里用到立刻執(zhí)行函數(shù)。這樣 console.log(i); 中的i就保存在每一次循環(huán)生成的立刻執(zhí)行函數(shù)中的作用域里了。

解決辦法二

for (let i = 0; i < 5; i++) {   //let 代替 var
  setTimeout(function (){
    console.log(i); 
   },1000); 
}

let 為代碼塊的作用域,所以每一次 for 循環(huán),console.log(i); 都引用到 for 代碼塊作用域下的i,因?yàn)檫@樣被引用,所以 for 循環(huán)結(jié)束后,這些作用域在 setTimeout 未執(zhí)行前都不會(huì)被釋放。

四、補(bǔ)充

在寫示例代碼的過(guò)程中,發(fā)現(xiàn)一個(gè)語(yǔ)法點(diǎn):

 function a(i){ 
  console.log(i);  
 }
for (var i = 0; i < 5; i++) { 
  setTimeout(a(i),1000); 
} 

報(bào)錯(cuò):

TypeError: "callback" argument must be a function
at setTimeout (timers.js:421:11)
……

百度了下,原來(lái) setTimeout 不支持傳帶參數(shù)的函數(shù),可以再用一個(gè)匿名函數(shù)包裝下它吧,見下面代碼:

function a(i){ 
  console.log(i);  
}
for (var i = 0; i < 5; i++) { 
  setTimeout(function(){ //用匿名函數(shù)包裝
    a(i);
  },1000); 
} 

總結(jié)

以上所述是小編給大家介紹的for循環(huán) + setTimeout 結(jié)合一些示例(前端面試題),希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • javascript實(shí)現(xiàn)圖片左右滾動(dòng)效果【可自動(dòng)滾動(dòng),有左右按鈕】

    javascript實(shí)現(xiàn)圖片左右滾動(dòng)效果【可自動(dòng)滾動(dòng),有左右按鈕】

    這篇文章主要介紹了javascript實(shí)現(xiàn)圖片左右滾動(dòng)效果,可實(shí)現(xiàn)自動(dòng)滾動(dòng),帶有左右按鈕功能,基于插件scrollPic.js實(shí)現(xiàn),附帶了相應(yīng)的demo源碼供讀者下載參考,需要的朋友可以參考下
    2016-09-09
  • 淺析Bootstrap縮略圖組件與警示框組件

    淺析Bootstrap縮略圖組件與警示框組件

    縮略圖在網(wǎng)站中最常用的就是產(chǎn)品列表頁(yè)面,一行顯示幾張圖片,有的在圖片底下帶有標(biāo)題、描述內(nèi)容、按鈕等信息。本文給大家介紹Bootstrap縮略圖組件與警示框組件,感興趣的朋友一起學(xué)習(xí)吧
    2016-04-04
  • JavaScript實(shí)現(xiàn)自己的DOM選擇器原理及代碼

    JavaScript實(shí)現(xiàn)自己的DOM選擇器原理及代碼

    實(shí)現(xiàn)自己的DOM選擇器時(shí)匹配行為也應(yīng)該和瀏覽原生匹配行為一致,接下來(lái)本文將詳細(xì)介紹下實(shí)現(xiàn)思路及方法,感興趣的你可以參考下或許對(duì)你鞏固知識(shí)有所幫助
    2013-03-03
  • php常見的頁(yè)面跳轉(zhuǎn)方法匯總

    php常見的頁(yè)面跳轉(zhuǎn)方法匯總

    Web系統(tǒng)中,從一個(gè)網(wǎng)頁(yè)跳轉(zhuǎn)到另一個(gè)網(wǎng)頁(yè),是LAMP項(xiàng)目中最常用的技術(shù)之一。頁(yè)面跳轉(zhuǎn)可能是由于用戶單擊鏈接、按鈕等引發(fā)的,也可能是系統(tǒng)自動(dòng)產(chǎn)生的。 此處介紹PHP中常用的實(shí)現(xiàn)頁(yè)面自動(dòng)跳轉(zhuǎn)的方法。
    2015-04-04
  • JS eval代碼快速解密實(shí)例解析

    JS eval代碼快速解密實(shí)例解析

    這篇文章主要介紹了JS eval代碼快速解密實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • 讓你更好使用Typescript的11個(gè)技巧分享

    讓你更好使用Typescript的11個(gè)技巧分享

    學(xué)習(xí)Typescript通常是一個(gè)重新發(fā)現(xiàn)的過(guò)程。本文將總結(jié)幾個(gè)技巧,幫助你充分發(fā)揮語(yǔ)言的潛力,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-01-01
  • TS中declare的簡(jiǎn)單使用方法

    TS中declare的簡(jiǎn)單使用方法

    declare 關(guān)鍵字用來(lái)告訴編譯器,某個(gè)類型是存在的,可以在當(dāng)前文件中使用,本文給大家介紹TS中declare的簡(jiǎn)單使用方法,感興趣的朋友一起看看吧
    2023-12-12
  • JavaScript實(shí)現(xiàn)為指定對(duì)象添加多個(gè)事件處理程序的方法

    JavaScript實(shí)現(xiàn)為指定對(duì)象添加多個(gè)事件處理程序的方法

    這篇文章主要介紹了JavaScript實(shí)現(xiàn)為指定對(duì)象添加多個(gè)事件處理程序的方法,可實(shí)現(xiàn)讓指定對(duì)象處理多個(gè)事件的功能,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-04-04
  • JavaScript中???、??=、?.和?||的區(qū)別淺析

    JavaScript中???、??=、?.和?||的區(qū)別淺析

    在?JS?中,???運(yùn)算符被稱為非空運(yùn)算符,下面這篇文章主要給大家介紹了關(guān)于JavaScript中???、??=、?.和?||區(qū)別的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • JavaScript去除空格的幾種方法

    JavaScript去除空格的幾種方法

    JavaScript去除空格的幾種方法...
    2006-10-10

最新評(píng)論