這兩天的GitHub Trending repositories被一個名叫?javascript-questions的項目霸榜了搀绣,項目中記錄了一些JavaScript題目飞袋。
我大概從頭到尾看了一遍,都是一些基礎(chǔ)的題目链患,我大概花了半個小時(有些題很簡單巧鸭,可以一掃而過)把這些題做完了,雖然題目很簡單麻捻,但是每道題都對應(yīng)一個知識點纲仍,如果這個知識點你沒有接觸過呀袱,那肯定會做錯,如果你接觸過這些知識點郑叠,那么這些題對你來說就很容易夜赵。
建議大家也花半個小時來做一做,以便查漏補缺乡革。
為方便大家能夠更快的做題寇僧,而不把時間浪費在翻譯上,我又花了幾個小時把它們翻譯成了中文沸版,當(dāng)然已經(jīng)獲得了作者授權(quán)嘁傀。
JavaScript 進階問題列表
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)存空間),默認值為undefined馒铃,直到我們實際執(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í)行機制逼裆,setTimeout函數(shù)真正被執(zhí)行時郁稍,循環(huán)已經(jīng)走完。 由于第一個循環(huán)中的變量i是使用var關(guān)鍵字聲明的胜宇,因此該值是全局的耀怜。 在循環(huá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'是一個真值妥曲。 我們實際上要問的是“這個真值是假的嗎贾费?”。 這會返回false檐盟。
5. 哪個選項是不正確的?
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纫骑。
但是蝎亚,使用點表示法,這不會發(fā)生先馆。?mouse沒有名為bird的鍵发框,這意味著mouse.bird是undefined。 然后煤墙,我們使用點符號來詢問size:mouse.bird.size梅惯。 由于mouse.bird是undefined宪拥,我們實際上是在詢問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è)置它們彼此相等時缔刹,所有對象都通過引用進行交互。
首先劣针,變量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)我們使用==運算符時煌张,它只檢查它是否具有相同的值。 他們都有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實例上不存在freddie方法:拋出TypeError看杭。
9. 下面代碼的輸出是什么?
let greeting;
greetign = {}; // Typo!
console.log(greetign);
A:?{}
B:?ReferenceError: greetign is not defined
C:?undefined
答案: A
控制臺會輸出空對象,因為我們剛剛在全局對象上創(chuàng)建了一個空對象挟伙! 當(dāng)我們錯誤地將greeting輸入為greetign時楼雹,JS解釋器實際上在瀏覽器中將其視為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中是可能的,因為函數(shù)也是對象G垂(原始類型之外的所有東西都是對象)
函數(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實例都需要這種方法。這會浪費大量內(nèi)存空間饺蚊,因為它們?nèi)匀痪哂性搶傩云加眨@占用了每個實例的內(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退盯。 我們實際做的是定義global.firstName ='Sarah'和global.lastName ='Smith。?sarah本身的返回值是undefined泻肯。
12. 事件傳播的三個階段是什么渊迁?
A: 目標(biāo) > 捕獲 > 冒泡
B: 冒泡 > 目標(biāo) > 捕獲
C: 目標(biāo) > 冒泡 > 捕獲
D: 捕獲 > 目標(biāo) > 冒泡
答案: D
在捕獲階段,事件通過父元素向下傳遞到目標(biāo)元素灶挟。 然后它到達目標(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)換椒楣。?強制從一種類型轉(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
后綴一元運算符++:
返回值(返回0)
增加值(數(shù)字現(xiàn)在是1)
前綴一元運算符++:
增加值(數(shù)字現(xiàn)在是2)
返回值(返回2)
所以返回0 2 2煌寇。
小結(jié)
文中如有錯誤焕蹄,歡迎在評論區(qū)指正,如果這篇文章幫助到了你阀溶,歡迎點贊和關(guān)注腻脏。
想閱讀更多優(yōu)質(zhì)文章、可關(guān)注我淌哟,你的點贊和關(guān)注是我持續(xù)創(chuàng)作的動力迹卢!
歡迎大家和我一起討論學(xué)習(xí),我們一起交流成長徒仓。
“我自己是一名從事了5年前端的老程序員腐碱,辭職目前在做講師,今年年初我花了一個月整理了一份最適合2019年學(xué)習(xí)的web前端干貨掉弛,從最基礎(chǔ)的HTML+CSS+JS到移動端HTML5到各種框架都有整理症见,送給每一位前端小伙伴,這里是小白聚集地殃饿,歡迎初學(xué)和進階中的小伙伴谋作。"
加微信:webtutou123 (領(lǐng)取)