金三銀四搞事季铺坞,前端這個近年的熱門領(lǐng)域,搞事氣氛特別強烈洲胖,我朋友小偉最近就在瘋狂面試济榨,遇到了許多有趣的面試官,有趣的面試題绿映,我來幫這個搞事 boy 轉(zhuǎn)述一下擒滑。
以下是我一個朋友的故事,真的不是我叉弦。
for(vari=0;i<5;i++){console.log(i);}
“小偉丐一,你說說這幾行代碼會輸出什么?”
當面試官在 Sublime 打出這幾行代碼時淹冰,我竟有點蒙蔽钝诚。蛤?這不是最簡單的一個循環(huán)嗎榄棵?是不是有陷阱啊凝颇,我思索一下潘拱,這好像和我看的那個閉包的題很像啊,這面試官是不是沒寫完芭÷浴芦岂?有毒啊。
“應該是直接輸出 0 到 4 吧...”垫蛆,我弱弱的說到禽最。
“是啊,別緊張袱饭,這題沒啥陷阱川无,我就是隨便寫一下÷枪裕”
(Excuse me懦趋?面試官你是來搞笑的嗎,嚇死老子了U钗丁)
“那你在看看這幾行代碼會輸出什么仅叫?”
for(vari=0;i<5;i++){setTimeout(function(){console.log(i);},1000*i);}
額,什么鬼糙捺,怎么還不是我背了那么多遍的那道閉包題诫咱,讓我想想。 setTimeout 會延遲執(zhí)行洪灯,那么執(zhí)行到 console.log 的時候坎缭,其實 i 已經(jīng)變成 5 了,對签钩,就是這樣幻锁,這么簡單怎么可能難到老子。
“應該是開始輸出一個 5边臼,然后每隔一秒再輸出一個 5,一共 5 個 5假消∧ⅲ”
“對,那應該怎么改才能輸出 0 到 4 呢富拗?”
終于到我熟悉的了臼予,加個閉包就解決了,穩(wěn)啃沪!
for(vari=0;i<5;i++){(function(i){setTimeout(function(){console.log(i);},i*1000);})(i);}
“很好粘拾,那你能說一下,我刪掉這個 i 會發(fā)生什么嗎创千?”
for(vari=0;i<5;i++){(function(){setTimeout(function(){console.log(i);},i*1000);})(i);}
“這樣子的話缰雇,內(nèi)部其實沒有對 i 保持引用入偷,其實會變成輸出 5⌒涤矗”
“很好疏之,那我給你改一下,你看看會輸出什么暇咆?”
for(vari=0;i<5;i++){setTimeout((function(i){console.log(i);})(i),i*1000);}
蛤锋爪?什么鬼,這是什么情況爸业,讓我想想其骄。這里給 setTimeout 傳遞了一個立即執(zhí)行函數(shù)。額扯旷,setTimeout 可以接受函數(shù)或者字符串作為參數(shù)拯爽,那么這里立即執(zhí)行函數(shù)是個啥呢,應該是個 undefined 薄霜,也就是說等價于:
setTimeout(undefined, ...);
而立即執(zhí)行函數(shù)會立即執(zhí)行某抓,那么應該是立馬輸出的。
“應該是立馬輸出 0 到 4 吧惰瓜》窀保”
“哎喲,不錯哦崎坊,最后一題备禀,你對 Promise 了解吧?”
“還可以吧...”
“OK奈揍,那你試試這道題曲尸。”
setTimeout(function(){console.log(1)},0);newPromise(functionexecutor(resolve){console.log(2);for(vari=0;i<10000;i++){i==9999&&resolve();}console.log(3);}).then(function(){console.log(4);});console.log(5);
WTFD泻病A砘肌!蛾绎!我想靜靜昆箕!
這道題應該考察我 JavaScript 的運行機制的,讓我理一下思路租冠。
首先先碰到一個 setTimeout鹏倘,于是會先設置一個定時,在定時結(jié)束后將傳遞這個函數(shù)放到任務隊列里面顽爹,因此開始肯定不會輸出 1 纤泵。
然后是一個 Promise,里面的函數(shù)是直接執(zhí)行的镜粤,因此應該直接輸出 2 3 捏题。
然后玻褪,Promise 的 then 應當會放到當前 tick 的最后,但是還是在當前 tick 中涉馅。
因此归园,應當先輸出 5,然后再輸出 4 稚矿。
最后在到下一個 tick庸诱,就是 1 。
“2 3 5 4 1”
“好滴晤揣,等待下一輪面試吧桥爽。”
So easy昧识!媽媽再也不用擔心我的面試了钠四。
以上文章,未經(jīng)考證跪楞,如有雷同缀去,純屬抄我!