做者:Dmitri Pavlutin翻譯:瘋狂的技術咋javascript
原文:https://dmitripavlutin.com/si...前端
未經容許嚴禁轉載java
在軟件開發中,我認爲最須要注意的是:程序員
不是 JavaScript,this
,CSS,IE 瀏覽器,而是上述兩點!面試
若是你參加 JavaScript 高級開發面試,那麼頗有可能在編碼面試中被問到一些棘手的問題。segmentfault
我知道這是不公平的。一些不知名的人將你放在一邊來審視你。這並非使人愉快的經歷。數組
你能作什麼?瀏覽器
請遵循如下建議:「經過實踐變得完美」。經過投入足夠的時間(最好地按期進行)來深刻了解 JavaScript,能夠改善你的編碼,而且做爲積極的結果,能夠改善面試技巧。服務器
在本文中,你將發現 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
是意外建立的全局變量。
在瀏覽器中,以上代碼片斷等效於:
const clothes = ['jacket', 't-shirt']; clothes.length = 0; clothes[0]; // => ???
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
的這種行爲,當 JavaScript 執行 clothes.length = 0
時,會刪除 clothes
數組中的全部項。
clothes[0]
是 undefined
, ,由於 clothes
數組已清空。
numbers
數組的內容是什麼:
const length = 4; const numbers = []; for (var i = 0; i < length; i++);{ numbers.push(i + 1); } numbers; // => ???
仔細看一下在花括號 {
前出現的分號;
:
在建立 null 語句 時,很容易忽略這個分號。null 語句是不執行任何操做的空語句。
for()
在 null 語句上迭代4次(不執行任何操做),而忽略將元素實際存入數組的代碼塊:{numbers.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進入代碼塊 { numbers.push(i + 1); }
一次,將 4 + 1
存入數組 numbers
。
所以,numbers
爲 [5]
。
好久之前,當我面試第一份工做時,有人問了我這個問題。
在此次面試中,我在 1 小時內回答了 20 個編碼問題。空語句問題也在其中。
當時急於解決問題,我沒有看到在大括號 {
以前的分號;
。因此我得出了錯誤的答案 [一、二、三、4]
。
因爲這種不公平的把戲,我有些失望。我問面試官,這種詭計背後的緣由是什麼?面試官回答:
「由於咱們須要高度重視細節的人。」
幸運的是,我最終並無爲那家公司工做。
究竟怎麼看待這件事,我將結論留給你本身作出。
arrayFromValue()
返回什麼值?
function arrayFromValue(item) { return [items]; } arrayFromValue(10); // => ???
很容易忽略關鍵字 return
和表達式 [items]
之間的換行。
換行符會使 JavaScript 自動在 return
和 [items]
表達式之間插入分號。
這是等效代碼,在 return
以後插入了分號:
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); }
若是你之前沒有據說過這個棘手的問題,則你的答案極可能是 0
,1
和 2
,這是錯誤的。當我第一次試着解決它時,這也是個人答案!
執行這段代碼的過程有兩個階段。
階段1
for()
迭代 3 次。在每次迭代時,都會建立一個新函數 log()
,該函數將捕獲變量 i
。而後,setTimout()
調度 log()
的執行。for()
循環完成時,變量 i
的值爲 3
。log()
是捕獲變量 i
的閉包,該變量在 for()
循環做用域的外部中定義。重要的是要了解閉包在詞法上捕獲了變量 i
。
階段2
第二階段發生在 100ms 以後:
log()
回調由 setTimeout()
調用。 log()
讀取變量 i
的當前值 3
,並把 3
log 到控制檯。這就是爲何控制檯輸出爲 3
, 3
和 3
的緣由。
你知道如何將代碼段修復爲輸出 0、1 和 3 嗎?請在下面的評論中寫下你的解決方案!
相等性檢查的結果是什麼?
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 myConst = 3.14
以前,const
變量處於臨時死區。
請遵循詳細介紹JavaScript變量提高一文中的指南,以更好地掌握提高。
你可能會認爲有些面試中的問題沒什麼用,我也有一樣的感受,特別是鷹眼測試。可是他們仍然可能會被問到。
不管如何,以上大多數問題都能真正評估你是否精通 JavaScript。若是你在閱讀本文時難以回答某些問題,則意味着這些是你接下來必需要去學習的內容!
在面試中提出棘手的問題是否公平?請在評論中寫下你的見解。