javascript
js for循环_JS 函数的执行时机(深入理解6个6)
定時(shí)器:setTimeout()
setTimeout() 方法用于在指定的毫秒數(shù)后調(diào)用函數(shù)或計(jì)算表達(dá)式提示: 1000 毫秒= 1 秒。 提示: 如果你只想重復(fù)執(zhí)行可以使用 setInterval() 方法。 提示: 使用 clearTimeout() 方法來(lái)阻止函數(shù)的執(zhí)行。
語(yǔ)法:setTimeout(x,y,z)
- x 函數(shù)function()
- y 時(shí)間(time)
- z 參數(shù)(會(huì)自動(dòng)傳入第一個(gè)參數(shù),也就是函數(shù)的參數(shù)中) 可省略
因?yàn)閟etTimeout含義是定時(shí)器,需要通過(guò)設(shè)置(觸發(fā))時(shí)間來(lái)調(diào)用代碼
假使設(shè)置的時(shí)間為3000,則在3000毫秒數(shù)彈出對(duì)話框“Hello” 假使設(shè)置的觸發(fā)時(shí)間為“0”時(shí),含義則為盡快調(diào)用
打個(gè)比喻:老板讓你清點(diǎn)運(yùn)來(lái)的箱子,當(dāng)數(shù)到第50個(gè),老板和你說(shuō)把結(jié)果寫(xiě)到紙上交給我。當(dāng)下肯定不能進(jìn)行記錄,因?yàn)橄渥舆€未清點(diǎn)完成;只有最后數(shù)完箱子后,才能在寫(xiě)到紙上交給老板
先把主代碼執(zhí)行完,之后才盡快執(zhí)行setTimeout中的代碼
JS執(zhí)行(調(diào)用)時(shí)機(jī)
面試題:6個(gè)6
思考:以下代碼會(huì)打印出什么?
let i=0 for(i=0;i<6;i++){setTimeout(()=>{console.log(i)},1000) }運(yùn)行上面代碼,看看會(huì)打印出什么結(jié)果
let i=0 for(i=0;i<6;i++){setTimeout(()=>{console.log(i)},1000) }- JS函數(shù)的調(diào)用時(shí)機(jī)不同,得到的結(jié)果不同。
- setTimeout() 方法用于在指定的毫秒數(shù)后調(diào)用函數(shù)或計(jì)算表達(dá)式;其意思就是盡快,而不是馬上。
解釋:因?yàn)閟etTimeout是一個(gè)異步任務(wù),執(zhí)行到這里的操作會(huì)被瀏覽器丟到另一個(gè)任務(wù)隊(duì)列里去, 瀏覽器這時(shí)候會(huì)繼續(xù)執(zhí)行for循環(huán)。每一次for循環(huán)的時(shí)候,setTimeout都執(zhí)行一次,但是里面的函數(shù)沒(méi)有被執(zhí)行,而是被放到了任務(wù)隊(duì)列里面,等待執(zhí)行,for循環(huán)了6次,就放了6次,當(dāng)主線程執(zhí)行完成后,才進(jìn)入任務(wù)隊(duì)列里面執(zhí)行。這時(shí)候因?yàn)閒or循環(huán)i=6了,所以輸出的全部都是6。
如何理解異步呢?
異步代碼不等待結(jié)果,直接進(jìn)行下面的代碼,所以定時(shí)器只是開(kāi)啟了,而沒(méi)有立即執(zhí)行里面的代碼,等到當(dāng)前運(yùn)行壞境的代碼執(zhí)行完之后再回來(lái)執(zhí)行定時(shí)器里面的代碼。總結(jié):異步就是不等待結(jié)果的代碼。
解釋二:如案例中所示,setTimeout的調(diào)用時(shí)間為“0”(盡快調(diào)用),只有當(dāng)主代碼執(zhí)行完一遍后才會(huì)執(zhí)行setTimeout(定時(shí)器),但這時(shí)i已經(jīng)為6,所以打印出數(shù)值6.
又因?yàn)闂l件:i<6,共執(zhí)行了6次(當(dāng)i等于6時(shí)跳出循環(huán)),所有結(jié)果為一共打印出6次6。
思考:那么怎么正確顯示?(如何打印出0、1、2、3、4、5)
方法一:let關(guān)鍵字
原理:每次進(jìn)入進(jìn)入循環(huán)時(shí),JS會(huì)把當(dāng)前的復(fù)制一份路i在循環(huán)空間里(i=0,i=1...) 不會(huì)跟隨新的i跟變化
JS變態(tài)之處:把let聲明寫(xiě)入for循環(huán)中,則會(huì)正常打印出 0、1、2、3、4、5 (服了JS,迎合新人)for(let i = 0; i<6; i++){setTimeout(()=>{console.log(i)},0) }解釋:因?yàn)閘et變量的作用域只能在當(dāng)前函數(shù)中,所以每次for循環(huán)生成的都是一個(gè)新的i,setTimeout里輸出的i就是這個(gè)新的i,這個(gè)i是不會(huì)變化的,所以輸出的就是正常的。
迦南:var、let、consts在JavaScript變量/常量的定義?zhuanlan.zhihu.com除了使用 for let 配合,還有什么其他方法可以打印出 0、1、2、3、4、5?
方法二:
for(i=0;i<6;i++){let j = isetTimeout(()=>{console.log(j)},1000) }方法三:閉包
for(var i=0;i<6;i++){!function(i){ //這是里面的i //在匿名函數(shù)前加上運(yùn)算符‘ !’,不生成新的全局變量(防止污染全局)setTimeout(()=>{console.log(i)},1000) //這是里面的i}(i) //這是外面的i //在匿名函數(shù)后加個(gè)()立即執(zhí)行,并把i當(dāng)作參數(shù)value傳入匿名函數(shù)循環(huán)執(zhí)行,參數(shù)i和匿名函數(shù)組成了閉包 }原理:
- 聲明匿名函數(shù) function(value){} 包裹 setTimeout()
- 然后再匿名函數(shù)前加上運(yùn)算符‘ !’,防止生成新的全局變量(避免污染全局)
- 在匿名函數(shù)后加個(gè)()立即調(diào)用,并把 i 當(dāng)作參數(shù) value 傳入匿名函數(shù)進(jìn)行調(diào)用
注意:參數(shù)i和匿名函數(shù)會(huì)組成了閉包
通過(guò)閉包,將i的變量駐留在內(nèi)存中,當(dāng)輸出j時(shí),引用的是外部函數(shù)A的變量值i,i的值是根據(jù)循環(huán)來(lái)的,執(zhí)行setTimeout時(shí)已經(jīng)確定了里面的的輸出了。
方法四:利用 setTimeout 的第三個(gè)參數(shù),將i傳進(jìn)去
let i for(i = 0; i<6; i++){setTimeout((value)=>{console.log(value)},0,i) //setTimeout 第三個(gè)參數(shù),聲明后這個(gè)參數(shù)可以將自身傳給第一個(gè)參數(shù) function(value), }原理:
使用setTimeout 的第三個(gè)參數(shù)--這個(gè)參數(shù)可以將自身傳給第一個(gè)參數(shù)也就是匿名函數(shù)function(value)中,作為所需要的參數(shù)value,value可默認(rèn)不寫(xiě)
而 i 共傳入6次(0,1,2,3,4,5),通過(guò)匿名函數(shù)即可打印出
通常不寫(xiě)第三個(gè)三處,如果默認(rèn)不寫(xiě)第三個(gè)參數(shù),則不會(huì)傳入函數(shù)
由于每次傳入的參數(shù)是從for循環(huán)里面取到的值,所以會(huì)依次輸出0~5
簡(jiǎn)單一句換:setTimeout的第三個(gè)參數(shù)作用,它就是當(dāng)作setTimeout第一個(gè)函數(shù)的參數(shù)
方法五:const關(guān)鍵字
let i for(i = 0; i<6; i++){const x = isetTimeout(()=>{console.log(x)}) }拓展例1:
function sum(x,y,z){console.log(x+y+z); } setTimeout(sum,1000,1,2,3);拓展例2:
var i=0; setTimeout(function(){console.log('第二次'+i) },3000,setTimeout(function(){console.log('第一次'+i);i++; },1000));最后依次輸出為 第一次0 第二次1可以看到第三個(gè)參數(shù)還可以是先執(zhí)行,然后再執(zhí)行函數(shù)
不過(guò)還要注意一點(diǎn)就是:
這種傳參方式在IE9及更低的版本下是不起作用的
setTimeout的意思
setTimeout(fn(),1000) f2()1000ms后盡快執(zhí)行fn(),不代表馬上執(zhí)行,如f2()中寫(xiě)了10000行代碼,需要花10秒執(zhí)行完,那么,fn()會(huì)在10秒之后執(zhí)行。
總結(jié)
以上是生活随笔為你收集整理的js for循环_JS 函数的执行时机(深入理解6个6)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python企业微信回调_回调模式
- 下一篇: 保本型银行理财产品的收益是多少?附公式和