七個簡單但棘手的 JS 面試問題

做者:Dmitri Pavlutin

翻譯:瘋狂的技術咋javascript

原文:https://dmitripavlutin.com/si...前端

未經容許嚴禁轉載java

在軟件開發中,我認爲最須要注意的是:程序員

  1. 編碼面試
  2. 有毒的主管或豬隊友

不是 JavaScript,this,CSS,IE 瀏覽器,而是上述兩點!面試

若是你參加 JavaScript 高級開發面試,那麼頗有可能在編碼面試中被問到一些棘手的問題。segmentfault

我知道這是不公平的。一些不知名的人將你放在一邊來審視你。這並非使人愉快的經歷。數組

你能作什麼?瀏覽器

請遵循如下建議:「經過實踐變得完美」。經過投入足夠的時間(最好地按期進行)來深刻了解 JavaScript,能夠改善你的編碼,而且做爲積極的結果,能夠改善面試技巧。服務器

在本文中,你將發現 7 個簡單而又棘手的 JavaScript 面試問題。微信

儘管這些問題看上去彷佛比較隨意,但它們涉及了 JavaScript 的重要概念。因此你最好在下次面試以前進行練習!

1. 意外的全局變量

問題

在如下代碼段中, typeof atypeof 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

image.png

b 是意外建立的全局變量。

在瀏覽器中,以上代碼片斷等效於:

const clothes = ['jacket', 't-shirt'];
clothes.length = 0;

clothes[0]; // => ???

typeof a'undefined'。變量 a 僅在 foo() 做用域內部聲明,而在做用域外部中不可用。

typeof b 的結果爲 'number'b 是值爲 0 的全局變量。

2. 數組長度屬性

問題

clothes[0] 的值是什麼:

const clothes = ['jacket', 't-shirt'];
clothes.length = 0;

clothes[0]; // => ???

答案

數組對象的 length 屬性具備特殊行爲

🏛減少 length 屬性的值有刪除當前數組元素(索引值在新舊長度值之間)的反作用。

因爲 length 的這種行爲,當 JavaScript 執行 clothes.length = 0 時,會刪除 clothes 數組中的全部項。

clothes[0]undefined, ,由於 clothes 數組已清空。

3.鷹眼測試

問題

numbers 數組的內容是什麼:

const length = 4;
const numbers = [];
for (var i = 0; i < length; i++);{
  numbers.push(i + 1);
}

numbers; // => ???

答案

仔細看一下在花括號 { 前出現的分號;

image.png

在建立 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]

因爲這種不公平的把戲,我有些失望。我問面試官,這種詭計背後的緣由是什麼?面試官回答:

「由於咱們須要高度重視細節的人。」

幸運的是,我最終並無爲那家公司工做。

究竟怎麼看待這件事,我將結論留給你本身作出。

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

請閱讀本節中有關自動分號插入的更多信息。

5.經典問題:棘手的閉包

問題

下腳本將在控制檯中輸出什麼:

let i;
for (i = 0; i < 3; i++) {
  const log = () => {
    console.log(i);
  }
  setTimeout(log, 100);
}

答案

若是你之前沒有據說過這個棘手的問題,則你的答案極可能是 012,這是錯誤的。當我第一次試着解決它時,這也是個人答案!

執行這段代碼的過程有兩個階段。

階段1

  1. for() 迭代 3 次。在每次迭代時,都會建立一個新函數 log(),該函數將捕獲變量 i。而後,setTimout() 調度 log() 的執行。
  2. for() 循環完成時,變量 i 的值爲 3

log() 是捕獲變量 i 的閉包,該變量在 for() 循環做用域的外部中定義。重要的是要了解閉包在詞法上捕獲了變量 i

階段2

第二階段發生在 100ms 以後:

  1. 3 個固定的 log() 回調由 setTimeout() 調用。 log() 讀取變量 i當前值 3,並把 3 log 到控制檯。

這就是爲何控制檯輸出爲 333 的緣由。

你知道如何將代碼段修復爲輸出 0、1 和 3 嗎?請在下面的評論中寫下你的解決方案!

6.浮點數

問題

相等性檢查的結果是什麼?

0.1 + 0.2 === 0.3 // => ???

答案

首先,讓咱們看一下 0.1 + 0.2 的值:

0.1 + 0.2; // => 0.30000000000000004

0.10.2 的和並不是等於 0.3,而是略大於 0.3

因爲以二進制方式對浮點數進行編碼,因此像浮點數相加之類的操做會產生舍入偏差。

簡而言之,直接比較浮點數並不精確。

所以, 0.1 + 0.2 === 0.3false

訪問 0.30000000000000004.com 能夠了解更多信息。

7. 提高

問題

若是在聲明前訪問 myVarmyConst,會發生什麼?

myVar;   // => ???
myConst; // => ???

var myVar = 'value';
const myConst = 3.14;

答案

提高和臨時死區是影響 JavaScript 變量生命週期的兩個重要概念。

image.png

聲明前訪問 myVar 的結果爲 undefined。在初始化以前,提高的 var 變量的值爲 undefined

可是,在聲明行以前訪問 myConst 會引起 ReferenceError。在代碼行 const myConst = 3.14 以前,const 變量處於臨時死區。

請遵循詳細介紹JavaScript變量提高一文中的指南,以更好地掌握提高。

8.關鍵要點

你可能會認爲有些面試中的問題沒什麼用,我也有一樣的感受,特別是鷹眼測試。可是他們仍然可能會被問到。

不管如何,以上大多數問題都能真正評估你是否精通 JavaScript。若是你在閱讀本文時難以回答某些問題,則意味着這些是你接下來必需要去學習的內容!

在面試中提出棘手的問題是否公平?請在評論中寫下你的見解。


本文首發微信公衆號:前端先鋒

歡迎掃描二維碼關注公衆號,天天都給你推送新鮮的前端技術文章

歡迎掃描二維碼關注公衆號,天天都給你推送新鮮的前端技術文章

歡迎繼續閱讀本專欄其它高贊文章:


相關文章
相關標籤/搜索