7 個沙雕又帶有陷阱的 JS 面試題

做者:Dmitri Pavlutinjavascript

譯者:前端小智html

來源:dmitripavlutin前端


阿(a)裏(li)雲(yun)服務器很便宜火爆,今年比去年便宜,10.24~11.11購買是1年86元,3年229元,能夠點我時行參與java


爲了保證的可讀性,本文采用意譯而非直譯。git

在 JS 面試中,常常會看到一些簡單而又沙雕的題目,這些題目包含一些陷阱,但這些在咱們規範的編碼下或者業務中基本不會出現。 有些面試官就是這樣,不專一於制定代碼的標準和規範上,卻用不規範的代碼去檢驗別人是否細心。github

這魔幻的世界就是一個攀比優越感的,我能考你,我就是比你優越,真實。面試

來看看這 7 個沙雕題目是哪些。數組

1. 偶然建立的全局變量

面試官問瀏覽器

在下面的代碼中 typeof atypeof b 結果各自是什麼?(沙雕)服務器

function foo() {
  let a = b = 0;
  a++;
  return a;
}

foo();
typeof a; // => ???
typeof b; // => ???
複製代碼

答案

這個代碼的重點在第二行:let a = b = 0。這個語句聲明瞭一個局部變量 a,可是它也聲明瞭一個全局變量b

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 的全局變量

2. 數組的 length 屬性

面試官問

clothes[0] 的值是什麼?(沙雕)

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

clothes[0]; // => ???
複製代碼

答案

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

減小 length 屬性的值的反作用是刪除 本身的 數組元素,這些元素的數組索引位於新舊長度值之間。

因爲 length 屬性行爲,當 JS 執行 clothes.length = 0 時,刪除全部的 clothes 項。 因此 clothes[0] 的值爲 undefined,由於 clothes 數組已被清空。

3.考驗眼力的魔幻題

面試官問

下面代碼中 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]    
複製代碼

用不規範的代碼去檢驗別人是否細心,我以爲很沙雕。

4.自動分號插入

面試官問

arrayFromValue() 返回什麼值?(沙雕)

function arrayFromValue(items) {
  return
    [items];
}

arrayFromValue(10); // => ???
複製代碼

答案

這裏須要注意的 return[items] 之間已經換行了,JS 會在換行之間自動插入分號。因此上面等價下面的代碼:

function arrayFromValue(items) {
  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);
}
複製代碼

答案

當你對 JS 基礎不是很瞭解的時候,很容易給出 0, 1, 2 的答案,我第一次在學校遇到這個題目也是這個答案。

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

階段1

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

  2. for() 循環完成時,變量 i 的值爲 3

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

階段 2

第二階段發生在 100 毫秒以後

setTimeout()調用 3log() 回調。log() 讀取變量 i 的當前值,即 3

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

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

7. 變量的提高

面試官問

若是在聲明以前訪問 myVarmyConst 會發生什麼?(能不能換個題)

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

原文:dmitripavlutin.com/simple-but-…

交流(歡迎加入羣,羣工做日都會發紅包,互動討論技術)

阿里雲最近在作活動,低至2折,有興趣能夠看看:promotion.aliyun.com/ntms/yunpar…

乾貨系列文章彙總以下,以爲不錯點個Star,歡迎 加羣 互相學習。

github.com/qq449245884…

由於篇幅的限制,今天的分享只到這裏。若是你們想了解更多的內容的話,能夠去掃一掃每篇文章最下面的二維碼,而後關注我們的微信公衆號,瞭解更多的資訊和有價值的內容。

clipboard.png

每次整理文章,通常都到2點才睡覺,一週4次左右,挺苦的,還望支持,給點鼓勵

相關文章
相關標籤/搜索