search
尋找貓咪~QQ 地點 桃園市桃園區 Taoyuan , Taoyuan

每個前端開發者必會的二十個JavaScript面試題

問題1:JavaScript 中

undefined

not defined

的區別

JavaScript 未聲明變數直接使用會拋出異常:

var name is not defined

,如果沒有處理異常,代碼就停止運行了。

但是,使用

typeof undeclared_variable

並不會產生異常,會直接返回 。

var

x;

// 聲明 xconsole

.log(x);

//output: undefinedconsole

.log(

typeof

y);

//output: undefinedconsole

.log(z);

// 拋出異常: ReferenceError: z is not defined

問題2:下面的代碼輸出什麼?正確的答案應該是

1undefined

。JavaScript中if語句求值其實使用

eval

函數,

eval(function f{})

返回

function f{}

也就是 。

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

var

k =

1

;

if

(

1

) {

eval

(

functionfoo

{}); k +=

typeof

foo; }

console

.log(k);上面的代碼輸出其實就是

1undefined

。為什麼那?我們查看下

eval

說明文檔即可獲得答案

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

恰恰

function f{}

語句的返回值是

undefined

,所以一切都說通了。

注意上面代碼和以下代碼不同。

var

k =

1

;

if

(

1

) {

functionfoo

{}; k +=

typeof

foo; }

console

.log(k);

// output 1function

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

每一個對象都會創建一個private方法的方法,這樣很耗費內存

觀察下面代碼

var

Employee =

function (name, company, salary)

{

this

.name = name ||

""

;

this

.company = company ||

""

;

this

.salary = salary ||

5000

;

// Private methodvar

increaseSalary =

function

{

this

.salary =

this

.salary +

1000

; };

// Public methodthis

.dispalyIncreasedSalary =

function

{ increaseSlary;

console

.log(

this

.salary); }; };

// Create Employee class objectvar

emp1 =

new

Employee(

"John""Pluto"3000

);

var

emp2 =

new

Employee(

"Merry""Pluto"2000

);

var

emp3 =

new

Employee(

"Ren""Pluto"2500

);

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

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

問題4:JavaScript中什麼是

閉包

?寫出一個例子

老生常談的問題了,閉包是在一個函數里聲明了另外一個函數,並且這個函數訪問了父函數作用域里的變數。

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

  • 它自己作用域的變數
  • 父函數作用域的變數
  • 全局作用域的變數
var

globalVar =

"abc"

;

// Parent self invoking function

(

functionouterFunction (outerArg)

{

// begin of scope outerFunction// Variable declared in outerFunction function scope var

outerFuncVar =

'x'

;

// Closure self-invoking function

(

functioninnerFunction (innerArg)

{

// begin of scope innerFunction// variable declared in innerFunction function scopevar

innerFuncVar =

"y"

;

console

.log(

"outerArg = "

+ outerArg +

"\n"

+

"outerFuncVar = "

+ outerFuncVar +

"\n"

+

"innerArg = "

+ innerArg +

"\n"

+

"innerFuncVar = "

+ innerFuncVar +

"\n"

+

"globalVar = "

+ globalVar); }

// end of scope innerFunction)(5); // Pass 5 as parameter

}

// end of scope outerFunction )(7); // Pass 7 as parameter

innerFunction is closure that is defined inside outerFunc

輸出很簡單:

outerArg

=

7outerFuncVar

= x

innerArg

=

5innerFuncVar

= y

globalVar

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

console

.log(mul(

2

)(

3

)(

4

));

// output : 24 console

.log(mul(

4

)(

3

)(

4

));

// output : 48

答案直接給出:

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

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

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

怎麼清空

arrayList

方法1

arrayList

= ;

直接改變arrayList所指向的對象,原對象並不改變。

方法2

arrayList.length = 0;

這種方法通過設置length=0 使原數組清除元素。

方法3

arrayList.splice

(0,

arrayList.length

);

和方法2相似

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

方法1

使用 Object.prototype.toString 來判斷是否是數組

functionisArray(obj)

{

returnObject

.prototype.toString.call( obj ) ===

'[object Array]'

; }

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

方法二

使用 原型鏈 來完成判斷

functionisArray(obj)

{

return

obj.__proto__ ===

Array

.prototype; }基本思想是利用 實例如果是某個構造函數構造出來的那麼 它的

__proto__

是指向構造函數的

prototype

屬性。

方法3

利用JQuery

functionisArray(obj)

{

return

$.isArray(obj) }

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

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

var

output = (

function(x)

{

delete

x;

return

x; })(

0

);

console

.log(output);輸出是 。

delete

操作符是將object的屬性刪去的操作。但是這裡的

x

是並不是對象的屬性,

delete

操作符並不能作用。問題9:下面代碼輸出什麼?

var

x =

1

;

var

output = (

function

{

delete

x;

return

x; });

console

.log(output);

deletex

是並不是對象的屬性,

delete

操作符並不能作用。問題10:下面代碼輸出什麼?

var

x = { foo :

1

};

var

output = (

function

{

delete

x.foo;

return

x.foo; });

console

.log(output);輸出是

undefined

。x雖然是全局變數,但是它是一個object。

delete

作用在

x.foo

上,成功的將

x.foo

刪去。所以返回

undefined

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

var

Employee = { company:

'xyz'

}

var

emp1 =

Object

.create(Employee);

delete

emp1.company

console

.log(emp1.company);輸出是

xyz

,這裡的 emp1 通過 prototype 繼承了 Employee的 company。emp1自己並沒有company屬性。所以delete操作符的作用是無效的。問題12:什麼是 ?在chrome下執行如下代碼,我們就可以看到

undefined x 1

的身影。

var

trees = [

"redwood""bay""cedar""oak""maple"

];

delete

trees[

3

];

console

.log(trees);當我們使用 delete 操作符刪除一個數組中的元素,這個元素的位置就會變成一個佔位符。列印出來就是

undefined x 1

注意如果我們使用

trees[3] === 'undefined × 1'

返回的是

false

。因為它僅僅是一種列印表示,並不是值變為

undefined x 1

。問題13:下面代碼輸出什麼?

var

trees = [

"xyz""xxxx""test""ryan""apple"

];

delete

trees[

3

];

console

.log(trees.length);

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

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

var

bar =

true

;

console

.log(bar +

0

);

console

.log(bar +

"xyz"

);

console

.log(bar +

true

);

console

.log(bar +

false

);

輸出是

1 truexyz 2 1

下面給出一個加法操作表

  • Number + Number -> 加法
  • Boolean + Number -> 加法
  • Boolean + Boolean -> 加法
  • Number + String -> 連接
  • String + Boolean -> 連接
  • String + String -> 連接
var

z =

1

, y = z =

typeof

y;

console

.log(y);輸出是

undefined

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

上面代碼等價於

var

z =

1

z =

typeof

y;

var

y = z;

console

.log(y);問題16:下面代碼輸出什麼?

var

foo =

functionbar

{

return12

; };

typeof

bar;

輸出是拋出異常,bar is not defined。如果想讓代碼正常運行,需要這樣修改代碼:

var

bar =

function

{

return12

; };

typeof

bar;

或者是

functionbar

{

return12

; };

typeof

bar;

明確說明這個下問題

var

foo =

functionbar

{

// foo is visible here // bar is visible hereconsole

.log(

typeof

bar);

// Work here : )

};

// bar is undefined here

問題17:兩種函數聲明有什麼區別?

var

foo =

function

{

// Some code

};

functionbar

{

// Some code

};

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

我們可以運行下如下代碼看看結果。

console

.log(foo)

console

.log(bar)

var

foo =

function

{

// Some code

};

functionbar

{

// Some code

};

輸出為

undefinedfunctionbar

{

// Some code

};

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

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

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

// foo bar的定義位置被提升functionbar

{

// Some code

};

var

foo;

console

.log(foo)

console

.log(bar) foo =

function

{

// Some code

};

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

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

var

salary =

"1000$"

; (

function

{

console

.log(

"Original salary was "

+ salary);

var

salary =

"5000$"

;

console

.log(

"My New Salary "

+ salary); });

輸出是

Original salary was undefined My

New

Salary

5000

$

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

var

salary =

"1000$"

; (

function

{

var

salary ;

console

.log(

"Original salary was "

+ salary); salary =

"5000$"

;

console

.log(

"My New Salary "

+ salary); });

instanceof

操作符?下面代碼輸出什麼?

functionfoo

{

return

foo; }

console

.log(

new

foo

instanceof

foo);

instanceof

操作符用來判斷是否當前對象是特定類的對象。

functionAnimal

{

//或者不寫return語句returnthis

; }

var

dog =

new

Animal; dog

instanceof

Animal

// Output : true

但是,這裡的foo定義為

functionfoo

{

return

foo; }

所以

// here bar is pointer to function foo{return foo}.var

bar =

new

foo;所以

new foo instanceof foo

返回 false問題20: 如果我們使用JavaScript的」關聯數組」,我們怎麼計算」關聯數組」的長度?

var

counterArray = {

A

:

3

,

B

:

4

}; counterArray[

"C"

] =

1

;

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

Object

.keys(counterArray).length

// Output 3

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

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

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



熱門推薦

本文由 yidianzixun 提供 原文連結

寵物協尋 相信 終究能找到回家的路
寫了7763篇文章,獲得2次喜歡
留言回覆
回覆
精彩推薦