若是你符合JavaScript高級開發人員的資格,在編碼面試中頗有可能會被問到一些刁鑽的問題。javascript
我知道這不公平。一些不知名的人把你放在角落上下打量,彷佛想看你是什麼作成的。這是一次不愉快的經歷。 java
你能作什麼?面試
遵循這個建議:「熟能生巧」。經過投入足夠的時間,更好地按期深刻了解JavaScript,將改善你的編碼,並順便提升你的面試技巧。數組
在這篇文章中,你會發現7個乍一看很簡單,但實際上很棘手的JavaScript面試題。瀏覽器
雖然一開始這些問題看起來是隨機的,可是它們試圖與JavaScript的重要概念掛鉤。因此你最好在下次面試前練習一下!bash
在如下代碼中,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
是一個偶然建立的全局變量。學習
在瀏覽器中,上述代碼片斷至關於:
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
的這種行爲,當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; // => ???
複製代碼
讓咱們仔細看看出如今左花括號{
前面的分號;
:
很容易忽略這個分號,而它建立了一個空語句。空語句是不作任何事情的語句。
for()
在空語句(什麼也不作)上循環了 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個編碼問題。空語句問題位列其中。 當我在匆忙中解決這個問題時,我沒有看到逗號
;
就在花括號{
的前面。因此我答錯成 [1,2,3,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
第2步在 100 毫秒後發生:
setTimeout()
調用了隊列中的3個log()
回調。log()
讀取變量 i
的當前值,即3
,並記錄到控制檯3
。
這就是爲何控制檯輸出3
, 3
和3
。
你知道怎樣讓代碼輸出 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 myConst = 3.14
以前,const
變量處於暫時死區。
查看指南 JavaScript 變量提高詳解 ,完全掌握變量提高的概念。
你能夠認爲有些問題對面試毫無用處。我也有一樣的感受,尤爲是關於鷹眼測試。儘管如此,仍是有人會問這些問題。
無論怎樣,這些問題中的大多數均可以測試你是否熟悉JavaScript。若是你在閱讀這篇文章的時候很難答出其中一些問題,這就是提示你接下來要學習什麼了!
在面試中問一些刁鑽的問題公平嗎?說說你的見解。
歡迎關注個人微信公衆號「1024譯站」,爲你奉上更多技術乾貨!