金三銀四搞事季潜慎,前端這個近年的熱門領(lǐng)域,搞事氣氛特別強烈蓖康,我朋友小偉最近就在瘋狂面試铐炫,遇到了許多有趣的面試官,有趣的面試題钓瞭,我來幫這個搞事 boy 轉(zhuǎn)述一下驳遵。
以下是我一個朋友的故事淫奔,真的不是我山涡。
for (var i = 0; i < 5; i++) {
console.log(i);
}
“小偉,你說說這幾行代碼會輸出什么?”
當(dāng)面試官在 Sublime 打出這幾行代碼時鸭丛,我竟有點蒙蔽竞穷。蛤?這不是最簡單的一個循環(huán)嗎鳞溉?是不是有陷阱啊瘾带,我思索一下,這好像和我看的那個閉包的題很像啊熟菲,這面試官是不是沒寫完翱凑?有毒啊抄罕。
“應(yīng)該是直接輸出 0 到 4 吧...”允蚣,我弱弱的說到。
“是啊呆贿,別緊張嚷兔,這題沒啥陷阱,我就是隨便寫一下做入∶拔”
(Excuse me?面試官你是來搞笑的嗎竟块,嚇死老子了:恕)
“那你在看看這幾行代碼會輸出什么?”
for (var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, 1000 * i);
}
額浪秘,什么鬼前弯,怎么還不是我背了那么多遍的那道閉包題,讓我想想秫逝。 setTimeout 會延遲執(zhí)行恕出,那么執(zhí)行到 console.log 的時候,其實 i 已經(jīng)變成 5 了违帆,對浙巫,就是這樣,這么簡單怎么可能難到老子刷后。
“應(yīng)該是開始輸出一個 5的畴,然后每隔一秒再輸出一個 5,一共 5 個 5尝胆∩ゲ茫”
“對,那應(yīng)該怎么改才能輸出 0 到 4 呢含衔?”
終于到我熟悉的了煎娇,加個閉包就解決了二庵,穩(wěn)!
for (var i = 0; i < 5; i++) {
(function(i) {
setTimeout(function() {
console.log(i);
}, i * 1000);
})(i);
}
“很好缓呛,那你能說一下催享,我刪掉這個 i 會發(fā)生什么嗎?”
for (var i = 0; i < 5; i++) {
(function() {
setTimeout(function() {
console.log(i);
}, i * 1000);
})(i);
}
“這樣子的話哟绊,內(nèi)部其實沒有對 i 保持引用因妙,其實會變成輸出 5∑彼瑁”
“很好攀涵,那我給你改一下,你看看會輸出什么洽沟?”
for (var i = 0; i < 5; i++) {
setTimeout((function(i) {
console.log(i);
})(i), i * 1000);
}
蛤汁果?什么鬼,這是什么情況玲躯,讓我想想据德。這里給 setTimeout 傳遞了一個立即執(zhí)行函數(shù)。額跷车,setTimeout 可以接受函數(shù)或者字符串作為參數(shù)棘利,那么這里立即執(zhí)行函數(shù)是個啥呢,應(yīng)該是個 undefined 朽缴,也就是說等價于:
setTimeout(undefined, ...);
而立即執(zhí)行函數(shù)會立即執(zhí)行善玫,那么應(yīng)該是立馬輸出的。
“應(yīng)該是立馬輸出 0 到 4 吧密强∶├桑”
“哎喲,不錯哦或渤,最后一題系冗,你對 Promise 了解吧?”
“還可以吧...”
“OK薪鹦,那你試試這道題掌敬。”
setTimeout(function() {
console.log(1)
}, 0);
new Promise(function executor(resolve) {
console.log(2);
for( var i=0 ; i<10000 ; i++ ) {
i == 9999 && resolve();
}
console.log(3);
}).then(function() {
console.log(4);
});
console.log(5);
WTF3卮拧1己Α!地熄!我想靜靜华临!
這道題應(yīng)該考察我 JavaScript 的運行機制的,讓我理一下思路端考。
首先先碰到一個 setTimeout雅潭,于是會先設(shè)置一個定時揭厚,在定時結(jié)束后將傳遞這個函數(shù)放到任務(wù)隊列里面,因此開始肯定不會輸出 1 寻馏。
然后是一個 Promise棋弥,里面的函數(shù)是直接執(zhí)行的核偿,因此應(yīng)該直接輸出 2 3 诚欠。
然后,Promise 的 then 應(yīng)當(dāng)會放到當(dāng)前 tick 的最后漾岳,但是還是在當(dāng)前 tick 中轰绵。
因此,應(yīng)當(dāng)先輸出 5尼荆,然后再輸出 4 左腔。
最后在到下一個 tick,就是 1 捅儒。
“2 3 5 4 1”
“好滴液样,等待下一輪面試吧∏苫梗”
So easy鞭莽!媽媽再也不用擔(dān)心我的面試了。
(我有一個前端學(xué)習(xí)交流QQ群:328058344 如果你在學(xué)習(xí)前端的過程中遇到什么問題麸祷,歡迎來我的QQ群提問澎怒,群里每天還會更新一些學(xué)習(xí)資源。禁止閑聊阶牍,非喜勿進喷面。)