20個必會的JavaScript面試題

發表於2017-03-25

問題1:JavaScript 中 undefinednot defined 的區別

JavaScript 未宣告變數直接使用會丟擲異常:var name is not defined,如果沒有處理異常,程式碼就停止執行了。
但是,使用typeof undeclared_variable並不會產生異常,會直接返回 undefined

問題2:下面的程式碼輸出什麼?

正確的答案應該是 1undefined

JavaScript中if語句求值其實使用eval函式,eval(function f(){}) 返回 function f(){} 也就是 true

下面我們可以把程式碼改造下,變成其等效程式碼。

上面的程式碼輸出其實就是 1undefined。為什麼那?我們檢視下 eval() 說明文件即可獲得答案

該方法只接受原始字串作為引數,如果 string 引數不是原始字串,那麼該方法將不作任何改變地返回。

恰恰 function f(){} 語句的返回值是 undefined,所以一切都說通了。

注意上面程式碼和以下程式碼不同。

問題3:在JavaScript中建立一個真正的private方法有什麼缺點?

每一個物件都會建立一個private方法的方法,這樣很耗費記憶體

觀察下面程式碼

在這裡 emp1,emp2,emp3都有一個increaseSalary私有方法的副本。

所以我們除非必要,非常不推薦使用私有方法。

問題4:JavaScript中什麼是閉包?寫出一個例子

老生常談的問題了,閉包是在一個函式裡宣告瞭另外一個函式,並且這個函式訪問了父函式作用域裡的變數。

下面給出一個閉包例子,它訪問了三個域的變數

  • 它自己作用域的變數
  • 父函式作用域的變數
  • 全域性作用域的變數

輸出很簡單:

問題5:寫一個mul函式,使用方法如下。

答案直接給出:

簡單說明下: mul 返回一個匿名函式,執行這個匿名函式又返回一個匿名函式,最裡面的匿名函式可以訪問 x,y,z 進而算出乘積返回即可。

對於JavaScript中的函式一般可以考察如下知識點:

  • 函式是一等公民
  • 函式可以有屬性,並且能連線到它的構造方法
  • 函式可以像一個變數一樣存在記憶體中
  • 函式可以當做引數傳給其他函式
  • 函式可以返回其他函式

問題6:JavaScript怎麼清空陣列?

怎麼清空 arrayList

方法1

直接改變arrayList所指向的物件,原物件並不改變。

方法2

這種方法通過設定length=0 使原陣列清除元素。

方法3

和方法2相似

問題7:怎麼判斷一個object是否是陣列(array)?

方法1

使用 Object.prototype.toString 來判斷是否是陣列

這裡使用call來使 toString 中 this 指向 obj。進而完成判斷

方法二

使用 原型鏈 來完成判斷

基本思想是利用 例項如果是某個建構函式構造出來的那麼 它的 __proto__是指向建構函式的 prototype屬性。

方法3

利用JQuery

JQuery isArray 的實現其實就是方法1

問題8:下面程式碼輸出什麼?

輸出是 0delete 操作符是將object的屬性刪去的操作。但是這裡的 x 是並不是物件的屬性, delete 操作符並不能作用。

問題9:下面程式碼輸出什麼?

輸出是 1delete 操作符是將object的屬性刪去的操作。但是這裡的 x 是並不是物件的屬性, delete 操作符並不能作用。

問題10:下面程式碼輸出什麼?

輸出是 undefined。x雖然是全域性變數,但是它是一個object。delete作用在x.foo上,成功的將x.foo刪去。所以返回undefined

問題11:下面程式碼輸出什麼?

輸出是 xyz,這裡的 emp1 通過 prototype 繼承了 Employee的 company。emp1自己並沒有company屬性。所以delete操作符的作用是無效的。

問題12:什麼是 undefined x 1

在chrome下執行如下程式碼,我們就可以看到undefined x 1的身影。

當我們使用 delete 操作符刪除一個陣列中的元素,這個元素的位置就會變成一個佔位符。列印出來就是undefined x 1
注意如果我們使用trees[3] === 'undefined × 1'返回的是 false。因為它僅僅是一種列印表示,並不是值變為undefined x 1

問題13:下面程式碼輸出什麼?

輸出是5。因為delete操作符並不是影響陣列的長度。

問題14:下面程式碼輸出什麼?

輸出是

下面給出一個加法操作表

  • Number + Number -> 加法
  • Boolean + Number -> 加法
  • Boolean + Boolean -> 加法
  • Number + String -> 連線
  • String + Boolean -> 連線
  • String + String -> 連線

問題15:下面程式碼輸出什麼?

輸出是 undefined。js中賦值操作結合律是右至左的 ,即從最右邊開始計算值賦值給左邊的變數。

上面程式碼等價於

問題16:下面程式碼輸出什麼?

輸出是丟擲異常,bar is not defined。如果想讓程式碼正常執行,需要這樣修改程式碼:

或者是

明確說明這個下問題

問題17:兩種函式宣告有什麼區別?

foo的定義是在執行時。想系統說明這個問題,我們要引入變數提升的這一概念。

我們可以執行下如下程式碼看看結果。

輸出為

為什麼那?為什麼 foo 列印出來是 undefined,而 bar列印出來卻是函式?

JavaScript在執行時,會將變數提升。

所以上面程式碼JavaScript 引擎在實際執行時按這個順序執行。

原始碼的輸出合理解釋了。

問題18:下面程式碼輸出什麼?

輸出是

這題同樣考察的是變數提升。等價於以下程式碼

問題19:什麼是 instanceof 操作符?下面程式碼輸出什麼?

instanceof操作符用來判斷是否當前物件是特定類的物件。

但是,這裡的foo定義為

所以

所以 new foo() instanceof foo 返回 false

問題20: 如果我們使用JavaScript的”關聯陣列”,我們怎麼計算”關聯陣列”的長度?

其實答案很簡單,直接計算key的數量就可以了。

面試題參考自: 21 Essential JavaScript Interview Questions | Codementor

本文給出的面試題答案只是很多合理答案中的幾個,可能會不全面,歡迎大家補充。

由於個人疏忽等原因,本文中難免會存在少量錯誤,歡迎大家批評指正。

相關文章