做者:Dmitri Pavlutin
譯者:前端小智
來源:dmitripavlutin
這幾天本身的公衆號無套路送現金 200+,參與方式以下
https://mp.weixin.qq.com/s/PT...
爲了保證的可讀性,本文采用意譯而非直譯。javascript
在 JS 面試中,常常會看到一些簡單而又沙雕的題目,這些題目包含一些陷阱,但這些在咱們規範的編碼下或者業務中基本不會出現。 有些面試官就是這樣,不專一於制定代碼的標準和規範上,卻用不規範的代碼去檢驗別人是否細心。html
這魔幻的世界就是一個攀比優越感的,我能考你,我就是比你優越,真實。前端
來看看這 7 個沙雕題目是哪些。java
面試官問git
在下面的代碼中 typeof a
和 typeof b
結果各自是什麼?(沙雕)github
function foo() { let a = b = 0; a++; return a; } foo(); typeof a; // => ??? typeof b; // => ???
答案面試
這個代碼的重點在第二行
:let a = b = 0
。這個語句聲明瞭一個局部變量 a
,可是它也聲明瞭一個全局變量b
。segmentfault
在 foo()
做用域或全局做用域中都沒有聲明變量 b
。所以 JS 引薦將b = 0
表達式解釋爲 window.b = 0
。數組
以下圖所示,函數 foo
中的 i
都是一個偶然建立的全局變量:瀏覽器
一樣,在我們的問題中,b
是一個偶然建立的全局變量。在瀏覽器中,上面的代碼至關於以下:
function foo() { let a; window.b = 0; a = window.b; a++; return a; } foo(); typeof a; // => 'undefined' typeof window.b; // => 'number'
typeof a
是 'undefined'
。變量 a
僅在 foo()
做用域中聲明,在外部做用域內不可用。
typeof b
結果是 'number'
。b
是一個值爲 0
的全局變量
面試官問
clothes[0]
的值是什麼?(沙雕)
const clothes = ['jacket', 't-shirt']; clothes.length = 0; clothes[0]; // => ???
答案
數組對象的 length
屬性具備一些特殊的行爲:
減小length
屬性的值的反作用是刪除本身的
數組元素,這些元素的數組索引位於新舊長度值之間。
因爲 length
屬性行爲,當 JS 執行 clothes.length = 0
時,刪除全部的 clothes
項。 因此 clothes[0]
的值爲 undefined
,由於 clothes
數組已被清空。
面試官問
下面代碼中 numbers 數組的內容是什麼? 注意 for()
後加了一個分號(;
),真是沙雕。
const length = 4; const numbers = []; for (var i = 0; i < length; i++);{ numbers.push(i + 1); } numbers; // => ???
答案
上面代碼中 for()
後加了一個分號(;
) ,加上分號,JS 會認爲該語句結束,因此 for 循環執行了4次空語句,當退出循環的時候,此時的 i 值爲 4。
而後執行 { numbers.push(i + 1); }
,因此最終 numbers
內容只有一個數字 5
。
上面的代碼至關於下面的代碼
const length = 4; const numbers = []; var i; for (i = 0; i < length; i++) { // does nothing } { // a simple block numbers.push(i + 1); } numbers; // => [5]
用不規範的代碼去檢驗別人是否細心,我以爲很沙雕。
面試官問
arrayFromValue()
返回什麼值?(沙雕)
function arrayFromValue(item) { return [items]; } arrayFromValue(10); // => ???
答案
這裏須要注意的 return
和 [items]
之間已經換行了,JS 會在換行之間自動插入分號。因此上面等價下面的代碼:
function arrayFromValue(item) { return; [items]; } arrayFromValue(10); // => undefined
return;
在函數內部使該函數返回 undefined
,因此 arrayFromValue(10)
的值爲 undefined
。
面試官問
下面的代碼執行結果是什麼?(能不能換個題)
let i; for (i = 0; i < 3; i++) { const log = () => { console.log(i); } setTimeout(log, 100); }
答案
當你對 JS 基礎不是很瞭解的時候,很容易給出 0, 1, 2
的答案,我第一次在學校遇到這個題目也是這個答案。
執行這段代碼的過程有兩個階段。
階段1
for()
迭代 3
次。在每次迭代時,都會建立一個新函數 log()
,該函數將捕獲變量 i
。而後,setTimout()
調度 log()
的執行。for()
循環完成時,變量 i
的值爲 3
。log()
是一個捕獲變量 i
的閉包,該變量在 for()
循環的外部做用域中定義。重要的是要了解閉包在詞法上捕獲了變量 i
。
階段 2
第二階段發生在 100
毫秒以後
setTimeout()調用 3
個 log()
回調。log()
讀取變量 i
的當前值,即 3
。
這就是爲何控制檯輸出爲 3
, 3
和 3
的緣由
其實還有一種解釋,就是計算機執行一條語句基本都是納秒級別的,因此執行一個簡單循環根本花費不了多少,當 100
毫秒後,for
早就跑完了,變量 i
已是退出循環的條件值。
面試官問
下面的代碼輸出是什麼? (能不能換個題)
0.1 + 0.2 === 0.3 // => ???
答案
首先,來看一下 0.1 + 0.2
的值
0.1 + 0.2; // => 0.30000000000000004
0.1
和 0.2
的和不等於 0.3
,但略高於 0.3
。
因爲以二進制方式對浮點數進行編碼,所以像浮點數相加之類的操做會產生舍入偏差。
所以, 0.1 + 0.2 === 0.3
是 false
。
面試官問
若是在聲明以前訪問 myVar
和 myConst
會發生什麼?(能不能換個題)
myVar; // => ??? myConst; // => ??? var myVar = 'value'; const myConst = 3.14;
答案
提高和時間死區是影響 JS 變量生命週期的兩個重要概念。
在聲明以前訪問 myVar
的結果是 undefined
,由於使用 var 聲明的變量會被提高且值爲 undefined
。
可是,在聲明行以前訪問 myConst
會引起 ReferenceError
。在代碼行 const myConst = 3.14
以前,const
變量處於臨時死區。
你有沒有感受上面的問題,有些是對面試毫無用處,特別是第3道題目。可是,仍是有一小部分的面試中會被問到。
固然,雖然都說是沙雕題目,但這些是能夠評估你是否精通 JS,仍是有咱們學習的知識的。
在面試中,你還遇到哪些像這樣的題目,歡迎留言討論。
代碼部署後可能存在的BUG無法實時知道,過後爲了解決這些BUG,花了大量的時間進行log 調試,這邊順便給你們推薦一個好用的BUG監控工具 Fundebug。
原文:https://dmitripavlutin.com/si...
阿里雲最近在作活動,低至2折,有興趣能夠看看:https://promotion.aliyun.com/...
乾貨系列文章彙總以下,以爲不錯點個Star,歡迎 加羣 互相學習。
https://github.com/qq44924588...
由於篇幅的限制,今天的分享只到這裏。若是你們想了解更多的內容的話,能夠去掃一掃每篇文章最下面的二維碼,而後關注我們的微信公衆號,瞭解更多的資訊和有價值的內容。
每次整理文章,通常都到2點才睡覺,一週4次左右,挺苦的,還望支持,給點鼓勵