轉(zhuǎn)載《43個(gè)JavaScript問題楞慈,并附有答案》
從基礎(chǔ)到進(jìn)階,測(cè)試你有多了解 JavaScript,刷新你的知識(shí)厨埋,或者幫助你的 coding 面試邪媳!
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ù)內(nèi)部,我們首先通過 var 關(guān)鍵字聲明了 name 變量雨效。這意味著變量被提升了(內(nèi)存空間在創(chuàng)建階段就被設(shè)置好了)迅涮,直到程序運(yùn)行到定義變量位置之前默認(rèn)值都是 undefined。因?yàn)楫?dāng)我們打印 name 變量時(shí)還沒有執(zhí)行到定義變量的位置徽龟,因此變量的值保持為 undefined叮姑。
通過 let 和 const 關(guān)鍵字聲明的變量也會(huì)提升,但是和 var 不同据悔,它們不會(huì)被初始化传透。在我們聲明(初始化)之前是不能訪問它們的。這個(gè)行為被稱之為暫時(shí)性死區(qū)极颓。當(dāng)我們?cè)噲D在聲明之前訪問它們時(shí)朱盐,JavaScript 將會(huì)拋出一個(gè) ReferenceError 錯(cuò)誤。
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 和 0 1 2
B: 0 1 2 和 3 3 3
C: 3 3 3 和 0 1 2
答案:C
由于 JavaScript 的事件循環(huán)兵琳,setTimeout 回調(diào)會(huì)在遍歷結(jié)束后才執(zhí)行。因?yàn)樵诘谝粋€(gè)遍歷中遍歷 i 是通過 var 關(guān)鍵字聲明的骇径,所以這個(gè)值是全局作用域下的躯肌。在遍歷過程中,我們通過一元操作符 ++ 來每次遞增 i 的值破衔。當(dāng) setTimeout 回調(diào)執(zhí)行的時(shí)候清女,i 的值等于 3。
在第二個(gè)遍歷中运敢,遍歷 i 是通過 let 關(guān)鍵字聲明的:通過 let 和 const 關(guān)鍵字聲明的變量是擁有塊級(jí)作用域(指的是任何在 {} 中的內(nèi)容)校仑。在每次的遍歷過程中,i 都有一個(gè)新值传惠,并且每個(gè)值都在循環(huán)內(nèi)的作用域中迄沫。
- 輸出是什么?
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 的值是一個(gè)常規(guī)函數(shù)卦方,但是 perimeter 的值是一個(gè)箭頭函數(shù)羊瘩。
對(duì)于箭頭函數(shù),this 關(guān)鍵字指向的是它當(dāng)前周圍作用域(簡單來說是包含箭頭函數(shù)的常規(guī)函數(shù)盼砍,如果沒有常規(guī)函數(shù)的話就是全局對(duì)象)尘吗,這個(gè)行為和常規(guī)函數(shù)不同。這意味著當(dāng)我們調(diào)用 perimeter 時(shí)浇坐,this 不是指向 shape 對(duì)象睬捶,而是它的周圍作用域(在例子中是 window)。
在 window 中沒有 radius 這個(gè)屬性近刘,因此返回 undefined擒贸。
- 輸出是什么臀晃?
+true;
!"Lydia";
A: 1 and false
B: false and NaN
C: false and false
答案 A
一元操作符加號(hào)嘗試將 bool 轉(zhuǎn)為 number。true 轉(zhuǎn)換為 number 的話為 1介劫,false 為 0徽惋。
字符串 'Lydia' 是一個(gè)真值,真值取反那么就返回 false座韵。
- 哪一個(gè)是正確的险绘?
const bird = {
size: 'small'
}
const mouse = {
name: 'Mickey',
small: true
}
答案: A
在 JavaScript 中,所有對(duì)象的 keys 都是字符串(除非對(duì)象是 Symbol)誉碴。盡管我們可能不會(huì)定義它們?yōu)樽址鹿祝鼈冊(cè)诘讓涌倳?huì)被轉(zhuǎn)換為字符串。
當(dāng)我們使用括號(hào)語法時(shí)([])翔烁,JavaScript 會(huì)解釋(或者 unboxes)語句渺氧。它首先看到第一個(gè)開始括號(hào) [ 并繼續(xù)前進(jìn)直到找到結(jié)束括號(hào) ]。只有這樣蹬屹,它才會(huì)計(jì)算語句的值侣背。
mouse[bird.size]:首先計(jì)算 bird.size,這會(huì)得到 small慨默。mouse["small"] 返回 true贩耐。
然后使用點(diǎn)語法的話,上面這一切都不會(huì)發(fā)生厦取。mouse 沒有 bird 這個(gè) key潮太,這也就意味著 mouse.bird 是 undefined。然后當(dāng)我們使用點(diǎn)語法 mouse.bird.size 時(shí)虾攻,因?yàn)?mouse.bird 是 undefined铡买,這也就變成了 undefined.size。這個(gè)行為是無效的霎箍,并且會(huì)拋出一個(gè)錯(cuò)誤類似 Cannot read property "size" of undefined奇钞。
- 輸出是什么?
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è)置兩個(gè)對(duì)象彼此相等時(shí)景埃,它們會(huì)通過引用進(jìn)行交互。
首先顶别,變量 c
的值是一個(gè)對(duì)象谷徙。接下來,我們給 d
分配了一個(gè)和 c
對(duì)象相同的引用驯绎。
因此當(dāng)我們改變其中一個(gè)對(duì)象時(shí)完慧,其實(shí)是改變了所有的對(duì)象。
- 輸出是什么剩失?
let a = 3
let b = new Number(3)
let c = 3
console.log(a == b)
console.log(a === b)
console.log(b === c)
答案: C
new Number() 是一個(gè)內(nèi)建的函數(shù)構(gòu)造器屈尼。雖然它看著像是一個(gè) number蛤织,但它實(shí)際上并不是一個(gè)真實(shí)的 number:它有一堆額外的功能并且它是一個(gè)對(duì)象。
當(dāng)我們使用 == 操作符時(shí)鸿染,它只會(huì)檢查兩者是否擁有相同的值。因?yàn)樗鼈兊闹刀际?3乞巧,因此返回 true涨椒。
然后,當(dāng)我們使用 === 操作符時(shí)绽媒,兩者的值以及類型都應(yīng)該是相同的蚕冬。new Number() 是一個(gè)對(duì)象而不是 number,因此返回 false是辕。
- 輸出是什么囤热?
class Chameleon {
static colorChange(newColor) {
this.newColor = newColor
return this.newColor
}
constructor({ newColor = 'green' } = {}) {
this.newColor = newColor
}
}
const freddie = new Chameleon({ newColor: 'purple' })
freddie.colorChange('orange')
答案: D
colorChange 是一個(gè)靜態(tài)方法。靜態(tài)方法被設(shè)計(jì)為只能被創(chuàng)建它們的構(gòu)造器使用(也就是 Chameleon)获三,并且不能傳遞給實(shí)例旁蔼。因?yàn)?freddie 是一個(gè)實(shí)例,靜態(tài)方法不能被實(shí)例使用疙教,因此拋出了 TypeError 錯(cuò)誤棺聊。
- 輸出是什么?
let greeting
greetign = {} // Typo!
console.log(greetign)
答案: A
代碼打印出了一個(gè)對(duì)象贞谓,這是因?yàn)槲覀冊(cè)谌謱?duì)象上創(chuàng)建了一個(gè)空對(duì)象站楚!當(dāng)我們將 greeting 寫錯(cuò)成 greetign 時(shí)革为,JS 解釋器實(shí)際在上瀏覽器中將它視為 global.greetign = {} (或者 window.greetign = {})。
為了避免這個(gè)為題,我們可以使用 `"use strict"嫡纠。這能確保當(dāng)你聲明變量時(shí)必須賦值。
10 . 當(dāng)我們這么做時(shí)齿梁,會(huì)發(fā)生什么烹植?
function bark() {
console.log('Woof!')
}
bark.animal = 'dog'
答案: A
這在 JavaScript 中是可以的,因?yàn)楹瘮?shù)是對(duì)象;φ濉(除了基本類型之外其他都是對(duì)象)
函數(shù)是一個(gè)特殊的對(duì)象广辰。你寫的這個(gè)代碼其實(shí)不是一個(gè)實(shí)際的函數(shù)。函數(shù)是一個(gè)擁有屬性的對(duì)象主之,并且屬性也可被調(diào)用择吊。
- 輸出是什么?
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
const member = new Person("Lydia", "Hallie");
Person.getFullName = function () {
return `${this.firstName} ${this.lastName}`;
}
console.log(member.getFullName());
A: TypeError
B: SyntaxError
C: Lydia Hallie
D: undefined undefined
答案: A
你不能像常規(guī)對(duì)象那樣槽奕,給構(gòu)造函數(shù)添加屬性几睛。如果你想一次性給所有實(shí)例添加特性,你應(yīng)該使用原型粤攒。因此本例中所森,使用如下方式:
Person.prototype.getFullName = function () {
return `${this.firstName} ${this.lastName}`;
}
這才會(huì)使 member.getFullName() 起作用囱持。為什么這么做有益的?假設(shè)我們將這個(gè)方法添加到構(gòu)造函數(shù)本身里焕济。也許不是每個(gè) Person 實(shí)例都需要這個(gè)方法纷妆。這將浪費(fèi)大量內(nèi)存空間,因?yàn)樗鼈內(nèi)匀痪哂性搶傩郧缙@將占用每個(gè)實(shí)例的內(nèi)存空間掩幢。相反,如果我們只將它添加到原型中上鞠,那么它只存在于內(nèi)存中的一個(gè)位置际邻,但是所有實(shí)例都可以訪問它!
- 輸出是什么芍阎?
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
對(duì)于 sarah世曾,我們沒有使用 new 關(guān)鍵字。當(dāng)使用 new 時(shí)谴咸,this 引用我們創(chuàng)建的空對(duì)象轮听。當(dāng)未使用 new 時(shí),this 引用的是全局對(duì)象(global object)岭佳。
我們說 this.firstName 等于 "Sarah"蕊程,并且 this.lastName 等于 "Smith"。實(shí)際上我們做的是驼唱,定義了 global.firstName = 'Sarah' 和 global.lastName = 'Smith'藻茂。而 sarah 本身是 undefined。
- 事件傳播的三個(gè)階段是什么玫恳?
A: Target > Capturing > Bubbling
B: Bubbling > Target > Capturing
C: Target > Bubbling > Capturing
D: Capturing > Target > Bubbling
答案: D
在捕獲(capturing)階段中辨赐,事件從祖先元素向下傳播到目標(biāo)元素。當(dāng)事件達(dá)到目標(biāo)(target)元素后京办,冒泡(bubbling)才開始掀序。
- 所有對(duì)象都有原型。
A: true
B: false
答案: B
除了基本對(duì)象(base object)惭婿,所有對(duì)象都有原型不恭。基本對(duì)象可以訪問一些方法和屬性财饥,比如 .toString换吧。這就是為什么你可以使用內(nèi)置的 JavaScript 方法!所有這些方法在原型上都是可用的钥星。雖然 JavaScript 不能直接在對(duì)象上找到這些方法沾瓦,但 JavaScript 會(huì)沿著原型鏈找到它們,以便于你使用。
- 輸出是什么贯莺?
function sum(a, b) {
return a + b
}
sum(1, '2')
JavaScript 是一種動(dòng)態(tài)類型語言:我們不指定某些變量的類型风喇。值可以在你不知道的情況下自動(dòng)轉(zhuǎn)換成另一種類型,這種類型稱為隱式類型轉(zhuǎn)換(implicit type coercion)缕探。Coercion 是指將一種類型轉(zhuǎn)換為另一種類型魂莫。
在本例中,JavaScript 將數(shù)字 1 轉(zhuǎn)換為字符串爹耗,以便函數(shù)有意義并返回一個(gè)值豁鲤。在數(shù)字類型(1)和字符串類型('2')相加時(shí),該數(shù)字被視為字符串鲸沮。我們可以連接字符串,比如 "Hello" + "World"锅论,這里發(fā)生的是 "1" + "2"讼溺,它返回 "12"。
- 輸出是什么最易?
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
) - 值自增(number 現(xiàn)在是
1
)
一元前自增運(yùn)算符 ++
:
- 值自增(number 現(xiàn)在是
2
) - 返回值(返回
2
)
結(jié)果是 0 2 2
.
- 輸出是什么怒坯?
function getPersonInfo(one, two, three) {
console.log(one)
console.log(two)
console.log(three)
}
const person = 'Lydia'
const age = 21
getPersonInfo`${person} is ${age} years old`
答案: B
如果使用標(biāo)記模板字面量,第一個(gè)參數(shù)的值總是包含字符串的數(shù)組藻懒。其余的參數(shù)獲取的是傳遞的表達(dá)式的值剔猿!
- 輸出是什么?
function checkAge(data) {
if (data === { age: 18 }) {
console.log('You are an adult!')
} else if (data == { age: 18 }) {
console.log('You are still an adult.')
} else {
console.log(`Hmm.. You don't have an age I guess`)
}
}
checkAge({ age: 18 })
A: You are an adult!
B: You are still an adult.
C: Hmm.. You don't have an age I guess
答案: C
在測(cè)試相等性時(shí)嬉荆,基本類型通過它們的值(value)進(jìn)行比較归敬,而對(duì)象通過它們的引用(reference)進(jìn)行比較。JavaScript 檢查對(duì)象是否具有對(duì)內(nèi)存中相同位置的引用鄙早。
題目中我們正在比較的兩個(gè)對(duì)象不是同一個(gè)引用:作為參數(shù)傳遞的對(duì)象引用的內(nèi)存位置汪茧,與用于判斷相等的對(duì)象所引用的內(nèi)存位置并不同。
這也是 { age: 18 } === { age: 18 } 和 { age: 18 } == { age: 18 } 都返回 false 的原因限番。
- 輸出是什么舱污?
function getAge(...args) {
console.log(typeof args)
}
getAge(21)
答案: C
擴(kuò)展運(yùn)算符(...args)會(huì)返回實(shí)參組成的數(shù)組。而數(shù)組是對(duì)象弥虐,因此 typeof args 返回 "object"扩灯。
- 輸出是什么?
function getAge() {
'use strict'
age = 21
console.log(age)
}
getAge()
答案: C
使用 "use strict"霜瘪,你可以確保不會(huì)意外地聲明全局變量珠插。我們從來沒有聲明變量 age,因?yàn)槲覀兪褂?"use strict"颖对,它將拋出一個(gè)引用錯(cuò)誤丧失。如果我們不使用 "use strict",它就會(huì)工作惜互,因?yàn)閷傩?age 會(huì)被添加到全局對(duì)象中了布讹。
- 輸出是什么琳拭?
const sum = eval('10*10+5')
A: 105
B: "105"
C: TypeError
D: "10*10+5"
代碼以字符串形式傳遞進(jìn)來,eval 對(duì)其求值描验。如果它是一個(gè)表達(dá)式白嘁,就像本例中那樣,它對(duì)表達(dá)式求值膘流。表達(dá)式是 10 * 10 + 5絮缅。這將返回?cái)?shù)字 105。
- cool_secret 可訪問多長時(shí)間呼股?
sessionStorage.setItem('cool_secret', 123)
A: 永遠(yuǎn)耕魄,數(shù)據(jù)不會(huì)丟失。
B: 當(dāng)用戶關(guān)掉標(biāo)簽頁時(shí)彭谁。
C: 當(dāng)用戶關(guān)掉整個(gè)瀏覽器吸奴,而不只是關(guān)掉標(biāo)簽頁。
D: 當(dāng)用戶關(guān)閉電腦時(shí)缠局。
答案: B
關(guān)閉 tab 標(biāo)簽頁 后则奥,sessionStorage 存儲(chǔ)的數(shù)據(jù)才會(huì)刪除。
如果使用 localStorage狭园,那么數(shù)據(jù)將永遠(yuǎn)在那里读处,除非調(diào)用了 localStorage.clear()。
- 輸出是什么唱矛?
var num = 8
var num = 10
console.log(num)
A: 8
B: 10
C: SyntaxError
D: ReferenceError
答案: B
使用 var 關(guān)鍵字罚舱,你可以用相同的名稱聲明多個(gè)變量。然后變量將保存最新的值绎谦。
你不能使用 let 或 const 來實(shí)現(xiàn)這一點(diǎn)馆匿,因?yàn)樗鼈兪菈K作用域的。
- 輸出是什么燥滑?
const obj = { 1: 'a', 2: 'b', 3: 'c' }
const set = new Set([1, 2, 3, 4, 5])
obj.hasOwnProperty('1')
obj.hasOwnProperty(1)
set.has('1')
set.has(1)
A: false true false true
B: false true true true
C: true true false true
D: true true true true
答案: C
所有對(duì)象的鍵(不包括 Symbol)在底層都是字符串渐北,即使你自己沒有將其作為字符串輸入。這就是為什么 obj.hasOwnProperty('1') 也返回 true铭拧。
對(duì)于集合赃蛛,它不是這樣工作的。在我們的集合中沒有 '1':set.has('1') 返回 false搀菩。它有數(shù)字類型為 1呕臂,set.has(1) 返回 true。
- 輸出是什么肪跋?
const obj = { a: 'one', b: 'two', a: 'three' }
console.log(obj)
A: { a: "one", b: "two" }
B: { b: "two", a: "three" }
C: { a: "three", b: "two" }
D: SyntaxError
答案: C
如果你有兩個(gè)名稱相同的鍵歧蒋,則鍵會(huì)被替換掉。它仍然位于第一個(gè)鍵出現(xiàn)的位置,但是值是最后出現(xiàn)那個(gè)鍵的值谜洽。
- JavaScript 全局執(zhí)行上下文為你做了兩件事:全局對(duì)象和 this 關(guān)鍵字萝映。
A: true
B: false
C: it depends
答案: A
基本執(zhí)行上下文是全局執(zhí)行上下文:它是代碼中隨處可訪問的內(nèi)容。
- 輸出是什么阐虚?
for (let i = 1; i < 5; i++) {
if (i === 3) continue
console.log(i)
}
A: 1 2
B: 1 2 3
C: 1 2 4
D: 1 3 4
答案: C
如果某個(gè)條件返回 true序臂,則 continue 語句跳過本次迭代。
- 輸出是什么实束?
String.prototype.giveLydiaPizza = () => {
return 'Just give Lydia pizza already!'
}
const name = 'Lydia'
name.giveLydiaPizza()
答案: A
String 是內(nèi)置的構(gòu)造函數(shù)奥秆,我們可以向它添加屬性。我只是在它的原型中添加了一個(gè)方法咸灿」苟基本類型字符串被自動(dòng)轉(zhuǎn)換為字符串對(duì)象,由字符串原型函數(shù)生成避矢。因此悼瘾,所有 string(string 對(duì)象)都可以訪問該方法!
- 輸出是什么谷异?
const a = {}
const b = { key: 'b' }
const c = { key: 'c' }
a[b] = 123
a[c] = 456
console.log(a[b])
A: 123
B: 456
C: undefined
D: ReferenceError
答案: B
對(duì)象的鍵被自動(dòng)轉(zhuǎn)換為字符串。我們?cè)噲D將一個(gè)對(duì)象 b 設(shè)置為對(duì)象 a 的鍵锦聊,且相應(yīng)的值為 123歹嘹。
然而,當(dāng)字符串化一個(gè)對(duì)象時(shí)孔庭,它會(huì)變成 "[object Object]"尺上。因此這里說的是,a["[object Object]"] = 123圆到。然后怎抛,我們?cè)僖淮巫隽送瑯拥氖虑椋琧 是另外一個(gè)對(duì)象芽淡,這里也有隱式字符串化马绝,于是,a["[object Object]"] = 456挣菲。
然后富稻,我們打印 a[b],也就是 a["[object Object]"]白胀。之前剛設(shè)置為 456椭赋,因此返回的是 456。
- 輸出是什么或杠?
const foo = () => console.log('First')
const bar = () => setTimeout(() => console.log('Second'))
const baz = () => console.log('Third')
bar()
foo()
baz()
A: First Second Third
B: First Third Second
C: Second First Third
D: Second Third First
答案: B
我們有一個(gè) setTimeout 函數(shù)哪怔,并首先調(diào)用它。然而,它是最后打印日志的认境。
這是因?yàn)樵跒g覽器中胚委,我們不僅有運(yùn)行時(shí)引擎,還有一個(gè)叫做 WebAPI 的東西元暴。WebAPI 提供了 setTimeout 函數(shù)篷扩,也包含其他的,例如 DOM茉盏。
將 callback 推送到 WebAPI 后鉴未,setTimeout 函數(shù)本身(但不是回調(diào)!)將從棧中彈出鸠姨。
現(xiàn)在铜秆,foo
被調(diào)用,打印 "First"
讶迁。
[圖片上傳失敗...(image-456753-1578203268239)]
foo
從棧中彈出连茧,baz
被調(diào)用. 打印 "Third"
。
[圖片上傳失敗...(image-decffe-1578203268239)]
WebAPI 不能隨時(shí)向棧內(nèi)添加內(nèi)容巍糯。相反啸驯,它將回調(diào)函數(shù)推到名為 queue 的地方。
[圖片上傳失敗...(image-8aa5be-1578203268239)]
這就是事件循環(huán)開始工作的地方祟峦。一個(gè)事件循環(huán)查看棧和任務(wù)隊(duì)列罚斗。如果棧是空的,它接受隊(duì)列上的第一個(gè)元素并將其推入棧宅楞。
[圖片上傳失敗...(image-6bc774-1578203268239)]
bar
被調(diào)用针姿,打印 "Second"
,然后它被棧彈出厌衙。
- 當(dāng)點(diǎn)擊按鈕時(shí)距淫,event.target是什么?
<div onclick="console.log('first div')">
<div onclick="console.log('second div')">
<button onclick="console.log('button')">
Click!
</button>
</div>
</div>
A: Outer div
B: Inner div
C: button
D: 一個(gè)包含所有嵌套元素的數(shù)組婶希。
答案: C
導(dǎo)致事件的最深嵌套的元素是事件的 target榕暇。你可以通過 event.stopPropagation 來停止冒泡。
- 當(dāng)您單擊該段落時(shí)喻杈,日志輸出是什么拐揭?
<div onclick="console.log('div')">
<p onclick="console.log('p')">
Click here!
</p>
</div>
答案: A
如果我們點(diǎn)擊 p,我們會(huì)看到兩個(gè)日志:p 和 div奕塑。在事件傳播期間堂污,有三個(gè)階段:捕獲、目標(biāo)和冒泡龄砰。默認(rèn)情況下盟猖,事件處理程序在冒泡階段執(zhí)行(除非將 useCapture 設(shè)置為 true)讨衣。它從嵌套最深的元素向外傳播。
- 輸出是什么式镐?
const person = { name: 'Lydia' }
function sayHi(age) {
console.log(`${this.name} is ${age}`)
}
sayHi.call(person, 21)
sayHi.bind(person, 21)
A: undefined is 21 Lydia is 21
B: function function
C: Lydia is 21 Lydia is 21
D: Lydia is 21 function
答案: D
使用這兩種方法反镇,我們都可以傳遞我們希望 this 關(guān)鍵字引用的對(duì)象。但是娘汞,.call 是立即執(zhí)行的歹茶。
.bind 返回函數(shù)的副本,但帶有綁定上下文你弦!它不是立即執(zhí)行的惊豺。
- 輸出是什么?
function sayHi() {
return (() => 0)()
}
typeof sayHi()
A: "object"
B: "number"
C: "function"
D: "undefined"
答案: B
sayHi 方法返回的是立即執(zhí)行函數(shù)(IIFE)的返回值.此立即執(zhí)行函數(shù)的返回值是 0禽作, 類型是 number
參考:只有7種內(nèi)置類型:null尸昧,undefined,boolean旷偿,number烹俗,string,object 和 symbol萍程。 function 不是一種類型幢妄,函數(shù)是對(duì)象,它的類型是object茫负。
- 下面哪些值是 falsy?
0
new Number(0)
('')
(' ')
new Boolean(false)
undefined
答案: A
只有 6 種 falsy 值:
undefined
null
NaN
0
-
''
(empty string) false
Function
構(gòu)造函數(shù), 比如 new Number
和 new Boolean
蕉鸳,是 truthy。
- 輸出是什么朽褪?
console.log(typeof typeof 1)
A: "number"
B: "string"
C: "object"
D: "undefined"
答案: B
typeof 1 返回 "number"置吓。 typeof "number" 返回 "string"无虚。
- 輸出是什么缔赠?
const numbers = [1, 2, 3]
numbers[10] = 11
console.log(numbers)
A: [1, 2, 3, 7 x null, 11]
B: [1, 2, 3, 11]
C: [1, 2, 3, 7 x empty, 11]
D: SyntaxError
答案: C
當(dāng)你為數(shù)組設(shè)置超過數(shù)組長度的值的時(shí)候, JavaScript 會(huì)創(chuàng)建名為 "empty slots" 的東西友题。它們的值實(shí)際上是 undefined嗤堰。你會(huì)看到以下場(chǎng)景:
[1, 2, 3, 7 x empty, 11]
這取決于你的運(yùn)行環(huán)境(每個(gè)瀏覽器,以及 node 環(huán)境度宦,都有可能不同)
- 輸出是什么踢匣?
(() => {
let x, y
try {
throw new Error()
} catch (x) {
(x = 1), (y = 2)
console.log(x)
}
console.log(x)
console.log(y)
})()
A: 1 undefined 2
B: undefined undefined undefined
C: 1 1 2
D: 1 undefined undefined
答案: A
catch 代碼塊接收參數(shù) x。當(dāng)我們傳遞參數(shù)時(shí)戈抄,這與之前定義的變量 x 不同 离唬。這個(gè) x 是屬于 catch 塊級(jí)作用域的。
然后划鸽,我們將塊級(jí)作用域中的變量賦值為 1输莺,同時(shí)也設(shè)置了變量 y 的值∑莅ィ現(xiàn)在,我們打印塊級(jí)作用域中的變量 x嫂用,值為 1型凳。
catch 塊之外的變量 x 的值仍為 undefined, y 的值為 2嘱函。當(dāng)我們?cè)?catch 塊之外執(zhí)行 console.log(x) 時(shí)甘畅,返回 undefined,y 返回 2往弓。
- JavaScript 中的一切都是疏唾?
A: 基本類型與對(duì)象
B: 函數(shù)與對(duì)象
C: 只有對(duì)象
D: 數(shù)字與對(duì)象
答案: A
JavaScript 只有基本類型和對(duì)象。
基本類型包括 boolean, null, undefined, bigint, number, string, symbol亮航。
- 輸出是什么荸实?
[[0, 1], [2, 3]].reduce(
(acc, cur) => {
return acc.concat(cur)
},
[1, 2]
)
答案: C
[1, 2]是初始值。初始值將會(huì)作為首次調(diào)用時(shí)第一個(gè)參數(shù) acc 的值缴淋。在第一次執(zhí)行時(shí)准给, acc 的值是 [1, 2], cur 的值是 [0, 1]重抖。合并它們露氮,結(jié)果為 [1, 2, 0, 1]。 第二次執(zhí)行钟沛, acc 的值是 [1, 2, 0, 1]畔规, cur 的值是 [2, 3]。合并它們恨统,最終結(jié)果為 [1, 2, 0, 1, 2, 3]
- 輸出是什么叁扫?
!!null
!!''
!!1
答案: B
null
是 falsy。 !null
的值是 true
畜埋。 !true
的值是 false
莫绣。
""
是 falsy。 !""
的值是 true
悠鞍。 !true
的值是 false
对室。
1
是 truthy。 !1
的值是 false
咖祭。 !false
的值是 true
掩宜。
- setInterval 方法的返回值是什么?
setInterval(() => console.log('Hi'), 1000)
A: 一個(gè)唯一的id
B: 該方法指定的毫秒數(shù)
C: 傳遞的函數(shù)
D: undefined
答案: A
setInterval 返回一個(gè)唯一的 id么翰。此 id 可被用于 clearInterval 函數(shù)來取消定時(shí)牺汤。
- 輸出是什么?
[...'Lydia']
A: ["L", "y", "d", "i", "a"]
B: ["Lydia"]
C: [[], "Lydia"]
D: [["L", "y", "d", "i", "a"]]
答案: A
string 類型是可迭代的浩嫌。擴(kuò)展運(yùn)算符將迭代的每個(gè)字符映射成一個(gè)元素檐迟。
- 輸出是什么?
function* generator(i) {
yield I;
yield i * 2;
}
const gen = generator(10);
console.log(gen.next().value);
console.log(gen.next().value);
A: [0, 10], [10, 20]
B: 20, 20
C: 10, 20
D: 0, 10 and 10, 20
一般的函數(shù)在執(zhí)行之后是不能中途停下的戴已。但是,生成器函數(shù)卻可以中途“停下”锅减,之后可以再從停下的地方繼續(xù)糖儡。當(dāng)生成器遇到y(tǒng)ield關(guān)鍵字的時(shí)候,會(huì)生成yield后面的值怔匣。注意握联,生成器在這種情況下不 返回 (return )值,而是 生成 (yield)值每瞒。
首先金闽,我們用10作為參數(shù)i來初始化生成器函數(shù)。然后使用next()方法一步步執(zhí)行生成器剿骨。第一次執(zhí)行生成器的時(shí)候代芜,i的值為10,遇到第一個(gè)yield關(guān)鍵字浓利,它要生成i的值挤庇。此時(shí),生成器“暫痛矗”嫡秕,生成了10。
然后苹威,我們?cè)賵?zhí)行next()方法昆咽。生成器會(huì)從剛才暫停的地方繼續(xù),這個(gè)時(shí)候i還是10牙甫。于是我們走到了第二個(gè)yield關(guān)鍵字處掷酗,這時(shí)候需要生成的值是i*2,i為10窟哺,那么此時(shí)生成的值便是20泻轰。所以這道題的最終結(jié)果是10,20。
- 返回值是什么?
const firstPromise = new Promise((res, rej) => {
setTimeout(res, 500, "one");
});
const secondPromise = new Promise((res, rej) => {
setTimeout(res, 100, "two");
});
Promise.race([firstPromise, secondPromise]).then(res => console.log(res));
A: "one"
B: "two"
C: "two" "one"
D: "one" "two"
答案: B
當(dāng)我們向Promise.race方法中傳入多個(gè)Promise時(shí)脏答,會(huì)進(jìn)行 優(yōu)先 解析糕殉。在這個(gè)例子中亩鬼,我們用setTimeout給firstPromise和secondPromise分別設(shè)定了500ms和100ms的定時(shí)器殖告。這意味著secondPromise會(huì)首先解析出字符串two。那么此時(shí)res參數(shù)即為two雳锋,是為輸出結(jié)果黄绩。
- 輸出是什么?
let person = { name: "Lydia" };
const members = [person];
person = null;
console.log(members);
A: null
B: [null]
C: [{}]
D: [{ name: "Lydia" }]
答案: D
首先我們聲明了一個(gè)擁有name
屬性的對(duì)象 person
。
然后我們又聲明了一個(gè)變量members
. 將首個(gè)元素賦值為變量person
玷过。 當(dāng)設(shè)置兩個(gè)對(duì)象彼此相等時(shí)爽丹,它們會(huì)通過 引用 進(jìn)行交互筑煮。但是當(dāng)你將引用從一個(gè)變量分配至另一個(gè)變量時(shí),其實(shí)只是執(zhí)行了一個(gè) 復(fù)制 操作粤蝎。(注意一點(diǎn)真仲,他們的引用 并不相同!)
接下來我們讓person
等于null
。
我們沒有修改數(shù)組第一個(gè)元素的值初澎,而只是修改了變量person
的值,因?yàn)樵兀◤?fù)制而來)的引用與person
不同秸应。members
的第一個(gè)元素仍然保持著對(duì)原始對(duì)象的引用。當(dāng)我們輸出members
數(shù)組時(shí)碑宴,第一個(gè)元素會(huì)將引用的對(duì)象打印出來软啼。
- 輸出是什么?
console.log(3 + 4 + "5");
A: "345"
B: "75"
C: 12
D: "12"
答案: B
當(dāng)所有運(yùn)算符的 優(yōu)先級(jí) 相同時(shí),計(jì)算表達(dá)式需要確定運(yùn)算符的結(jié)合順序延柠,即從右到左還是從左往右祸挪。在這個(gè)例子中,我們只有一類運(yùn)算符+贞间,對(duì)于加法來說贿条,結(jié)合順序就是從左到右。
3 + 4首先計(jì)算增热,得到數(shù)字7.
由于類型的強(qiáng)制轉(zhuǎn)換闪唆,7 + '5'的結(jié)果是"75". JavaScript將7轉(zhuǎn)換成了字符串,可以參考問題15.我們可以用+號(hào)把兩個(gè)字符串連接起來钓葫。 "7" + "5" 就得到了"75".
- num的值是什么?
const num = parseInt("7*6", 10);
A: 42
B: "42"
C: 7
D: NaN
答案: C
只返回了字符串中第一個(gè)字母. 設(shè)定了 進(jìn)制 后 (也就是第二個(gè)參數(shù)悄蕾,指定需要解析的數(shù)字是什么進(jìn)制: 十進(jìn)制、十六機(jī)制础浮、八進(jìn)制帆调、二進(jìn)制等等……),parseInt 檢查字符串中的字符是否合法. 一旦遇到一個(gè)在指定進(jìn)制中不合法的字符后,立即停止解析并且忽略后面所有的字符豆同。
*就是不合法的數(shù)字字符番刊。所以只解析到"7",并將其解析為十進(jìn)制的7. num的值即為7.
- 輸出是什么?
[1, 2, 3].map(num => {
if (typeof num === "number") return;
return num * 2;
});
A: []
B: [null, null, null]
C: [undefined, undefined, undefined]
D: [ 3 x empty ]
答案: C
對(duì)數(shù)組進(jìn)行映射的時(shí)候,num就是當(dāng)前循環(huán)到的元素. 在這個(gè)例子中影锈,所有的映射都是number類型芹务,所以if中的判斷typeof num === "number"結(jié)果都是true.map函數(shù)創(chuàng)建了新數(shù)組并且將函數(shù)的返回值插入數(shù)組。
但是鸭廷,沒有任何值返回枣抱。當(dāng)函數(shù)沒有返回任何值時(shí),即默認(rèn)返回undefined.對(duì)數(shù)組中的每一個(gè)元素來說辆床,函數(shù)塊都得到了這個(gè)返回值佳晶,所以結(jié)果中每一個(gè)元素都是undefined.