滿滿干貨!送你15道JavaScript面試題!

這兩天的GitHub Trending repositories被一個名叫?javascript-questions的項(xiàng)目霸榜了,項(xiàng)目中記錄了一些JavaScript題目。

我大概從頭到尾看了一遍,都是一些基礎(chǔ)的題目,我大概花了半個小時(有些題很簡單,可以一掃而過)把這些題做完了,雖然題目很簡單,但是每道題都對應(yīng)一個知識點(diǎn),如果這個知識點(diǎn)你沒有接觸過,那肯定會做錯,如果你接觸過這些知識點(diǎn),那么這些題對你來說就很容易。

建議大家也花半個小時來做一做,以便查漏補(bǔ)缺。

為方便大家能夠更快的做題,而不把時間浪費(fèi)在翻譯上,我又花了幾個小時把它們翻譯成了中文,當(dāng)然已經(jīng)獲得了作者授權(quán)。

JavaScript 進(jìn)階問題列表

1. 下面代碼的輸出是什么?

function sayHi {

console.log(name);

console.log(age);

var name = "Lydia";

let age = 21;

}

sayHi;

A:?Lydia?和?undefined

B:?Lydia?和?ReferenceError

C:?ReferenceError?和?21

D:?undefined?和?ReferenceError

答案: D

在函數(shù)中,我們首先使用var關(guān)鍵字聲明了name變量。 這意味著變量在創(chuàng)建階段會被提升(JavaScript會在創(chuàng)建變量創(chuàng)建階段為其分配內(nèi)存空間),默認(rèn)值為undefined,直到我們實(shí)際執(zhí)行到使用該變量的行。 我們還沒有為name變量賦值,所以它仍然保持undefined的值。

使用let關(guān)鍵字(和const)聲明的變量也會存在變量提升,但與var不同,初始化沒有被提升。 在我們聲明(初始化)它們之前,它們是不可訪問的。 這被稱為“暫時死區(qū)”。 當(dāng)我們在聲明變量之前嘗試訪問變量時,JavaScript會拋出一個ReferenceError。

2. 下面代碼的輸出是什么?

for (var i = 0; i < 3; i++) {

setTimeout( => console.log(i), 1);

}

for (let i = 0; i < 3; i++) {

setTimeout( => console.log(i), 1);

}

A:?0 1 2?and?0 1 2

B:?0 1 2?and?3 3 3

C:?3 3 3?and?0 1 2

答案: C

由于JavaScript中的事件執(zhí)行機(jī)制,setTimeout函數(shù)真正被執(zhí)行時,循環(huán)已經(jīng)走完。 由于第一個循環(huán)中的變量i是使用var關(guān)鍵字聲明的,因此該值是全局的。 在循環(huán)期間,我們每次使用一元運(yùn)算符++都會將i的值增加1。 因此在第一個例子中,當(dāng)調(diào)用setTimeout函數(shù)時,i已經(jīng)被賦值為3。

在第二個循環(huán)中,使用let關(guān)鍵字聲明變量i:使用let(和const)關(guān)鍵字聲明的變量是具有塊作用域的(塊是{}之間的任何東西)。 在每次迭代期間,i將被創(chuàng)建為一個新值,并且每個值都會存在于循環(huán)內(nèi)的塊級作用域。

3. 下面代碼的輸出是什么?

const shape = {

radius: 10,

diameter {

return this.radius * 2;

},

perimeter: => 2 * Math.PI * this.radius

};

shape.diameter;

shape.perimeter;

A:?20?and?62.83185307179586

B:?20?and?NaN

C:?20?and?63

D:?NaN?and?63

答案: B

請注意,diameter是普通函數(shù),而perimeter是箭頭函數(shù)。

對于箭頭函數(shù),this關(guān)鍵字指向是它所在上下文(定義時的位置)的環(huán)境,與普通函數(shù)不同! 這意味著當(dāng)我們調(diào)用perimeter時,它不是指向shape對象,而是指其定義時的環(huán)境(window)。沒有值radius屬性,返回undefined。

4. 下面代碼的輸出是什么?

+true;

!"Lydia";

A:?1?and?false

B:?false?and?NaN

C:?false?and?false

答案: A

一元加號會嘗試將boolean類型轉(zhuǎn)換為數(shù)字類型。?true被轉(zhuǎn)換為1,false被轉(zhuǎn)換為0。

字符串'Lydia'是一個真值。 我們實(shí)際上要問的是“這個真值是假的嗎?”。 這會返回false。

5. 哪個選項(xiàng)是不正確的?

const bird = {

size: "small"

};

const mouse = {

name: "Mickey",

small: true

};

A:?mouse.bird.size

B:?mouse[bird.size]

C:?mouse[bird["size"]]

D: All of them are valid

答案: A

在JavaScript中,所有對象鍵都是字符串(除了Symbol)。盡管有時我們可能不會給定字符串類型,但它們總是被轉(zhuǎn)換為字符串。

JavaScript解釋語句。當(dāng)我們使用方括號表示法時,它會看到第一個左括號[,然后繼續(xù),直到找到右括號]。只有在那個時候,它才會對這個語句求值。

mouse [bird.size]:首先它會對bird.size求值,得到small。?mouse [“small”]返回true。

但是,使用點(diǎn)表示法,這不會發(fā)生。?mouse沒有名為bird的鍵,這意味著mouse.bird是undefined。 然后,我們使用點(diǎn)符號來詢問size:mouse.bird.size。 由于mouse.bird是undefined,我們實(shí)際上是在詢問undefined.size。 這是無效的,并將拋出Cannot read property "size" of undefined。

6. 下面代碼的輸出是什么?

let c = { greeting: "Hey!" };

let d;

d = c;

c.greeting = "Hello";

console.log(d.greeting);

A:?Hello

B:?undefined

C:?ReferenceError

D:?TypeError

答案: A

在JavaScript中,當(dāng)設(shè)置它們彼此相等時,所有對象都通過引用進(jìn)行交互。

首先,變量c為對象保存一個值。 之后,我們將d指定為c與對象相同的引用。

更改一個對象時,可以更改所有對象。

7. 下面代碼的輸出是什么?

let a = 3;

let b = new Number(3);

let c = 3;

console.log(a == b);

console.log(a === b);

console.log(b === c);

A:?true?false?true

B:?false?false?true

C:?true?false?false

D:?false?true?true

答案: C

new Number是一個內(nèi)置的函數(shù)構(gòu)造函數(shù)。 雖然它看起來像一個數(shù)字,但它并不是一個真正的數(shù)字:它有一堆額外的功能,是一個對象。

當(dāng)我們使用==運(yùn)算符時,它只檢查它是否具有相同的值。 他們都有3的值,所以它返回true。

然而,當(dāng)我們使用===操作符時,類型和值都需要相等,new Number不是一個數(shù)字,是一個對象類型。兩者都返回?false。

8. 下面代碼的輸出是什么?

class Chameleon {

static colorChange(newColor) {

this.newColor = newColor;

}

constructor({ newColor = "green" } = {}) {

this.newColor = newColor;

}

}

const freddie = new Chameleon({ newColor: "purple" });

freddie.colorChange("orange");

A:?orange

B:?purple

C:?green

D:?TypeError

答案: D

colorChange方法是靜態(tài)的。 靜態(tài)方法僅在創(chuàng)建它們的構(gòu)造函數(shù)中存在,并且不能傳遞給任何子級。 由于freddie是一個子級對象,函數(shù)不會傳遞,所以在freddie實(shí)例上不存在freddie方法:拋出TypeError。

9. 下面代碼的輸出是什么?

let greeting;

greetign = {}; // Typo!

console.log(greetign);

A:?{}

B:?ReferenceError: greetign is not defined

C:?undefined

答案: A

控制臺會輸出空對象,因?yàn)槲覀儎倓傇谌謱ο笊蟿?chuàng)建了一個空對象! 當(dāng)我們錯誤地將greeting輸入為greetign時,JS解釋器實(shí)際上在瀏覽器中將其視為global.greetign = {}(或window.greetign = {})。

為了避免這種情況,我們可以使用“use strict”。 這可以確保在將變量賦值之前必須聲明變量。

10. 當(dāng)我們這樣做時會發(fā)生什么?

function bark {

console.log("Woof!");

}

bark.animal = "dog";

A: Nothing, this is totally fine!

B:?SyntaxError. You cannot add properties to a function this way.

C:?undefined

D:?ReferenceError

答案: A

這在JavaScript中是可能的,因?yàn)楹瘮?shù)也是對象!(原始類型之外的所有東西都是對象)

函數(shù)是一種特殊類型的對象。您自己編寫的代碼并不是實(shí)際的函數(shù)。 該函數(shù)是具有屬性的對象,此屬性是可調(diào)用的。

11. 下面代碼的輸出是什么?

function Person(firstName, lastName) {

this.firstName = firstName;

this.lastName = lastName;

}

const member = new Person("Lydia", "Hallie");

Person.getFullName = => this.firstName + this.lastName;

console.log(member.getFullName);

A:?TypeError

B:?SyntaxError

C:?Lydia Hallie

D:?undefined?undefined

答案: A

您不能像使用常規(guī)對象那樣向構(gòu)造函數(shù)添加屬性。 如果要一次向所有對象添加功能,則必須使用原型。 所以在這種情況下應(yīng)該這樣寫:

Person.prototype.getFullName = function {

return `${this.firstName} ${this.lastName}`;

}

這樣會使member.getFullName是可用的,為什么樣做是對的? 假設(shè)我們將此方法添加到構(gòu)造函數(shù)本身。 也許不是每個Person實(shí)例都需要這種方法。這會浪費(fèi)大量內(nèi)存空間,因?yàn)樗鼈內(nèi)匀痪哂性搶傩?,這占用了每個實(shí)例的內(nèi)存空間。 相反,如果我們只將它添加到原型中,我們只需將它放在內(nèi)存中的一個位置,但它們都可以訪問它!

12. 下面代碼的輸出是什么?

function Person(firstName, lastName) {

this.firstName = firstName;

this.lastName = lastName;

}

const lydia = new Person("Lydia", "Hallie");

const sarah = Person("Sarah", "Smith");

console.log(lydia);

console.log(sarah);

A:?Person {firstName: "Lydia", lastName: "Hallie"}?and?undefined

B:?Person {firstName: "Lydia", lastName: "Hallie"}?and?Person {firstName: "Sarah", lastName: "Smith"}

C:?Person {firstName: "Lydia", lastName: "Hallie"}?and?{}

D:Person {firstName: "Lydia", lastName: "Hallie"}?and?ReferenceError

答案: A

對于sarah,我們沒有使用new關(guān)鍵字。 使用new時,它指的是我們創(chuàng)建的新空對象。 但是,如果你不添加new它指的是全局對象!

我們指定了this.firstName等于'Sarah和this.lastName等于Smith。 我們實(shí)際做的是定義global.firstName ='Sarah'和global.lastName ='Smith。?sarah本身的返回值是undefined。

12. 事件傳播的三個階段是什么?

A: 目標(biāo) > 捕獲 > 冒泡

B: 冒泡 > 目標(biāo) > 捕獲

C: 目標(biāo) > 冒泡 > 捕獲

D: 捕獲 > 目標(biāo) > 冒泡

答案: D

在捕獲階段,事件通過父元素向下傳遞到目標(biāo)元素。 然后它到達(dá)目標(biāo)元素,冒泡開始。

13. 所有對象都有原型.

A: 對

B: 錯誤

答案: B

基礎(chǔ)對象外,所有對象都有原型。 基礎(chǔ)對象可以訪問某些方法和屬性,例如.toString。 這就是您可以使用內(nèi)置JavaScript方法的原因! 所有這些方法都可以在原型上找到。 雖然JavaScript無法直接在您的對象上找到它,但它會沿著原型鏈向下尋找并在那里找到它,這使您可以訪問它。

14. 下面代碼的輸出是什么?

function sum(a, b) {

return a + b;

}

sum(1, "2");

A:?NaN

B:?TypeError

C:?"12"

D:?3

答案: C

JavaScript是一種動態(tài)類型語言:我們沒有指定某些變量的類型。 在您不知情的情況下,值可以自動轉(zhuǎn)換為另一種類型,稱為隱式類型轉(zhuǎn)換。?強(qiáng)制從一種類型轉(zhuǎn)換為另一種類型。

在此示例中,JavaScript將數(shù)字1轉(zhuǎn)換為字符串,以使函數(shù)有意義并返回值。 在讓數(shù)字類型(1)和字符串類型('2')相加時,該數(shù)字被視為字符串。 我們可以連接像“Hello”+“World”這樣的字符串,所以這里發(fā)生的是“1”+“2”返回“12”。

15. 下面代碼的輸出是什么?

let number = 0;

console.log(number++);

console.log(++number);

console.log(number);

A:?1?1?2

B:?1?2?2

C:?0?2?2

D:?0?1?2

答案: C

后綴一元運(yùn)算符++:

返回值(返回0)

增加值(數(shù)字現(xiàn)在是1)

前綴一元運(yùn)算符++:

增加值(數(shù)字現(xiàn)在是2)

返回值(返回2)

所以返回0 2 2。

小結(jié)

文中如有錯誤,歡迎在評論區(qū)指正,如果這篇文章幫助到了你,歡迎點(diǎn)贊和關(guān)注。

想閱讀更多優(yōu)質(zhì)文章、可關(guān)注我,你的點(diǎn)贊和關(guān)注是我持續(xù)創(chuàng)作的動力!

歡迎大家和我一起討論學(xué)習(xí),我們一起交流成長。

“我自己是一名從事了5年前端的老程序員,辭職目前在做講師,今年年初我花了一個月整理了一份最適合2019年學(xué)習(xí)的web前端干貨,從最基礎(chǔ)的HTML+CSS+JS到移動端HTML5到各種框架都有整理,送給每一位前端小伙伴,這里是小白聚集地,歡迎初學(xué)和進(jìn)階中的小伙伴。"

加微信:webtutou123 (領(lǐng)?。?/p>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容