若是您符合高級開發人員的資格,其工做涉及JavaScript,那麼在編碼面試中頗有可能會被問到棘手的問題。javascript
遵循這個建議:「熟能生巧」。深刻有規律地學習JavaScript將提升您的編碼能力,而且能夠提升您的面試技巧。java
在這篇文章中,你會發現7個乍一看很簡單但很棘手的JavaScript面試問題。面試
雖然一開始這些問題看起來是隨意的,可是它們試圖與JavaScript的重要概念掛鉤。因此你最好在下次面試前練習一下!數組
如下代碼段中用於運算 typeof a
和 typeof b
的內容:瀏覽器
function foo() { let a = b = 0; a++; return a; } foo(); typeof a; // => ??? typeof b; // => ???
讓咱們看一下第2行:let a = b = 0
,該語句聲明一個局部變量a,然兒,它也聲明瞭全局變量b。閉包
在 foo()
範圍或全局範圍中都沒有聲明變量b。所以JavaScript將 b = 0
表達式解釋爲 window.b = 0
。換句話說,b是意外建立的全局變量。ide
在瀏覽器中,以上代碼片斷等效於:函數
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()
範圍內,而在外部範圍內不使用。學習
由於b是一個值爲0的全局變量,因此b的類型的值爲 'number'
。測試
clothes[0]
的值是什麼?
const clothes = ['jacket', 't-shirt']; clothes.length = 0; clothes[0]; // => ???
數組對象的 length
屬性具備特殊的行爲:減小length屬性的值的反作用是刪除本身的數組元素。所以,當JavaScript執行 clothes.length = 0
的時候將刪除全部元素。
clothes [0]
等於 undefined
的,由於 clothes
數組已被清空。
numbers
數組的內容是什麼?
const length = 4; const numbers = []; for (var i = 0; i < length; i++);{ numbers.push(i + 1); } numbers; // => ???
讓咱們仔細看一下分號 ;
出如今左大括號 {
:
這個分號很容易被忽略,它建立了一個空語句。空語句是不作任何事情的空語句。
for()
在空語句上進行4次迭代(不執行任何操做),而忽略實際將項目推入數組的塊:{number.push(i + 1);}
。上面的代碼等效於如下代碼:
const length = 4; const numbers = []; var i; for (i = 0; i < length; i++) { // does nothing } { // a simple block numbers.push(i + 1); } numbers; // => [5]
for()
將 i
變量遞增到4,而後JavaScript一次進入塊 {number.push(i + 1);}
,將 4 +1
推入數字數組。
所以,numbers
數組的內容爲 [5]
。
arrayFromValue()
返回什麼值?
function arrayFromValue(item) { return [item]; } arrayFromValue(10); // => ???
很容易錯過 return
關鍵字和 [item]
表達式之間的換行符。此換行符使JavaScript自動在 return
和 [item]
表達式之間插入分號。
這是等效的代碼,在返回後插入了分號:
function arrayFromValue(item) { return; [item]; } arrayFromValue(10); // => undefined
return;
函數內部使其返回 undefined
。所以 arrayFromValue(10)
的值爲 undefined
。
如下代碼將輸出什麼到控制檯?
let i; for (i = 0; i < 3; i++) { const log = () => { console.log(i); } setTimeout(log, 100); }
若是您之前從未據說過這個棘手的問題,則極可能您的答案是 0
、1
和 2
:這是錯誤的。當我第一次嘗試解決它時,這也是個人答案!
執行此代碼段有兩個階段。
for()
重複3次,在每次迭代過程當中,都會建立一個新的函數 log()
來捕獲變量 i
。而後 setTimout()
計劃執行log()
。for()
循環完成時,i
變量的值爲 3
。log()
是一個捕獲變量 i
的閉包,該變量在 for()
循環的外部範圍中定義。請務必注意,閉包能夠詞法捕獲 i
變量。
第二階段發生在100ms以後:setTimeout()
調用了3次計劃的 log()
。log()
讀取變量i的當前值爲3,並記錄到控制檯3。這就是爲何控制檯輸出爲3
、3
和 3
的緣由。
若是您難以理解閉包,建議閱讀 「 JavaScript閉包的簡單說明」。
您知道如何將代碼段記錄爲0、1和2嗎?請在下面的評論中寫下您的解決方案!
這個等式的結果是什麼?
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
。
點擊 0.30000000000000004.com 瞭解更多信息。
若是在聲明前訪問 myVar
和 myConst
,會發生什麼狀況?
myVar; // => ??? myConst; // => ??? var myVar = 'value'; const myConst = 3.14;
提高和臨時死區是影響JavaScript變量生命週期的兩個重要概念。
在聲明以前訪問 myVar
的結果爲 undefined
。在初始化以前,提高的 var 變量具備 undefined
的值。
然兒,在聲明行以前訪問 myConst
會引起 ReferenceError
。const
變量處於臨時死區,直到聲明行 const myConst = 3.14
。
您能夠認爲某些問題對面試毫無用處。我有一樣的感受,特別是關於鷹眼測試。儘管如此,他們可能會被問到。
不管如何,其中許多問題均可以真正評估您是否精通JavaScript,例如棘手的閉包。若是您在閱讀帖子時遇到一些困難,這很好地代表了您接下來必須學習什麼!
在面試中提出棘手的問題是否公平?讓我知道你的意見。
原文:https://dmitripavlutin.com/simple-but-tricky-javascript-interview-questions/
做者:Dmitri Pavlutin
翻譯:作工程師不作碼農