100 道 JavaScript 面試題及答案匯總(下)

英文 | https://betterprogramming.pub/100-javascript-interview-questions-58e22e30f7f1
翻譯 | 楊小二
let p1 = new Promise(function(resolve, reject) {setTimeout(resolve, 500, 'the first promise');});let p2 = new Promise(function(resolve, reject) {setTimeout(resolve, 100, 'the second promise');});Promise.race([p1, p2]).then(function(value) {console.log(value, 'was faster');});
the second promise was faster52、 promise.all() 方法有什么作用?
Promise.all 是一個將一系列承諾作為輸入的承諾。它在以下情況下得到解決:
要么所有的輸入承諾都得到解決。
或者他們中的任何一個被拒絕。
例如, promise.all 等待所有這三個 promise 完成:
var prom1 = new Promise((resolve, reject) => {setTimeout(() => {resolve("Yay!");}, 1000);});var prom2 = Promise.resolve(10);var prom3 = 100;Promise.all([prom1, prom2, prom3]).then(values => {console.log(values);});
["Yay", 10, 100]53、 eval() 函數(shù)是什么?
eval() 函數(shù)計算字符串中的代碼。要計算的字符串可以是表達式、變量、語句或語句序列。
例如:
console.log(eval("5+10"));1554、什么是事件冒泡?
在事件冒泡中,事件通過最里面的元素運行事件處理程序開始。然后它觸發(fā)父母的事件處理程序,直到它到達最外面的元素。
看到這一點的最佳方法是創(chuàng)建一個在 div 中包含 div 的 HTML 文檔:
<style>body * {margin: 20px;border: 1px solid blue;}</style><div onclick="alert('Outer layer')">Outer layer<div onclick="alert('Middle layer')">Middle layer<div onclick="alert('Inner layer')">Inner layer</div></div></div>
在每個 div 中,都有一個 JavaScript 警報,當(dāng)單擊該 div 時會觸發(fā)該警報。
結(jié)果頁面如下所示:

如果你現(xiàn)在單擊內(nèi)層,它會觸發(fā)分配給該 div 的警報,并觸發(fā)父 div 的警報。
55、 什么是時間死區(qū)?
時間死區(qū)意味著變量不可達,即使它已經(jīng)在范圍內(nèi)。
讓我們首先看看,當(dāng)你嘗試將未初始化的變量記錄到控制臺時會發(fā)生什么:
console.log(x);var x = "Yay";
undefined你可能希望這會導(dǎo)致錯誤,但它會打印 undefined。
發(fā)生這種情況是因為所有聲明都被移到了作用域的頂部。由于提升,上面的代碼在引擎蓋下的行為如下:
var x;console.log(x);x = "Yay";
這里 undefined 被自動分配給頂部的變量。這使得在定義它之前使用它成為可能。
但是讓我們看看當(dāng)我們使用 let 而不是 var 做同樣的事情時會發(fā)生什么:
console.log(x);let x = 10;
error: Uncaught ReferenceError: Cannot access 'x' before initialization發(fā)生這種情況是因為 let 的提升方式與 var 不同。當(dāng)一個 let 變量被提升時,它不會變成未定義的。相反,它是無法訪問的,或者在被分配值之前處于時間死區(qū)。
56、什么是URI?
URI 或統(tǒng)一資源標(biāo)識符是一組區(qū)分資源的字符。URI 允許互聯(lián)網(wǎng)協(xié)議在資源之間執(zhí)行操作。
URI 可能如下所示:
hello://example.com:8042/there?name=jack#sumthing57、什么是DOM?
當(dāng)網(wǎng)頁加載完畢后,瀏覽器會為該頁面創(chuàng)建一個 DOM。這使 JavaScript 能夠創(chuàng)建動態(tài) HTML。
DOM 或文檔對象模型充當(dāng) HTML 文檔的 API。它定義了文檔的結(jié)構(gòu)。它還指定如何訪問和修改文檔。
58、文檔加載還是 DOMContentLoaded?
DOMContentLoaded 事件在 HTML 文檔被加載和解析后被觸發(fā)。它不會等待資產(chǎn)(例如樣式表和圖像)。
文檔加載事件僅在整個頁面加載后觸發(fā),包括所有資產(chǎn)。
例如,以下是如何使用 DOMContentLoaded 在 DOM 已完全加載時發(fā)出通知:
window.addEventListener('DOMContentLoaded', (event) => {console.log('DOM is now loaded!');});
window.addEventListener('load', (event) => {console.log('The page is now loaded!');});
59、HTML 屬性 vs DOM 屬性?
當(dāng)你編寫 HTML 時,你可以在 HTML 元素上定義屬性。然后,當(dāng)你使用瀏覽器打開頁面時,你的 HTML 代碼將被解析。
至此,一個DOM節(jié)點就創(chuàng)建好了。這個 DOM 節(jié)點對應(yīng)于你剛剛編寫的 HTML 文檔。這個 DOM 節(jié)點是一個具有屬性的對象。
例如,這個 HTML 元素:
<input id="my-input" type="text" value="Name:">具有三個屬性,id、type 和 value。
當(dāng)瀏覽器解析這個 HTML 元素時。
它接受這個輸入字段并從中烘焙一個 HTMLInputElement 對象。
這個對象有幾十個屬性,比如accept、accesKey、align。
它還將一些原始 HTML 屬性轉(zhuǎn)換為屬性,例如 id 和類型。但是例如, value 屬性不引用 value 屬性。
60、什么是同源政策?
同源策略是一種有價值的安全機制。它可以防止 JavaScript 跨越域邊界發(fā)出請求。
源是指 URI 方案、主機名和端口號。同源策略使得一個頁面上的腳本無法訪問另一頁面上的敏感數(shù)據(jù)。
61、JavaScript 是編譯型語言還是解釋型語言?
JavaScript 是一種解釋型語言。
瀏覽器中的解釋器讀取 JavaScript 代碼,解釋每一行,然后運行它。
62、JavaScript 是區(qū)分大小寫的語言嗎?
JavaScript 是一種區(qū)分大小寫的語言。
關(guān)鍵字、變量、函數(shù)名等需要大寫一致。
為了演示,這段代碼有效
let i = 1;while(i < 2) {console.log(i);i++;}
let i = 1;WHILE(i < 2) {console.log(i);i++;}
63、JavaScript 有多少個線程?
JavaScript 使用單個線程。它不允許編寫解釋器可以在多個線程或進程中并行運行的代碼。
這意味著它按順序執(zhí)行代碼,并且必須先執(zhí)行完一段代碼,然后才能轉(zhuǎn)到下一段代碼。
看到這一點的一個很好的例子是當(dāng)你在網(wǎng)頁上顯示警報時。警報彈出后,在警報關(guān)閉之前,你無法與頁面交互。
alert("Hello there!");64、 “break”語句有什么作用?
break 語句跳出循環(huán)并繼續(xù)執(zhí)行循環(huán)外的代碼。
例如,此循環(huán)在遇到數(shù)字 5 后終止:
for (var i = 0; i < 100; i++) {if (i === 5) {break;}console.log('Number is ', i);}console.log('Yay');
Number is 0Number is 1Number is 2Number is 3Number is 4Yay
65、 “continue”語句的作用是什么?
continue 語句跳過一輪循環(huán)。
例如,這個循環(huán)跳過數(shù)字 2 和 3:
for (var i = 0; i < 5; i++) {if (i === 2 || i === 3) {continue;}console.log('Number is ', i);}
014
66、什么是正則表達式?
正則表達式,也稱為 regex 或 regexp,是形成搜索模式的一組字符。它是一種常用于 JavaScript 和其他編程語言的模式匹配工具。
例如,讓我們使用正則表達式從字符串中查找任何數(shù)字:
var regex = /\d+/g;var string = "You have 100 seconds time to run";var matches = string.match(regex);console.log(matches);
[100]例如,正則表達式可用于在大型文本文件中搜索電子郵件或電話號碼。
67、調(diào)試代碼時斷點的目的是什么?
斷點允許你查找 JavaScript 代碼中的錯誤。
當(dāng)執(zhí)行調(diào)試器語句并出現(xiàn)調(diào)試器窗口時,你可以在代碼中設(shè)置斷點。
在斷點處,JavaScript 停止執(zhí)行并讓你檢查值和范圍以解決可能的問題。
68、什么是條件運算符?
條件運算符是編寫 if-else 語句的簡寫。條件運算符有時稱為三元運算符。
例如:
// Regular if-else expression:const age = 10;if(age < 18){console.log("Minor");} else {console.log("Adult");}// Conditional operator shorthand for the above if-elseage < 18 ? console.log("Minor") : console.log("Adult");
69、你能鏈接條件運算符嗎?
對的,這是可能的。有時它很有用,因為它可以使代碼更易于理解。
讓我們看一個例子:
function example() {if (condition1) { return value1; }else if (condition2) { return value2; }else if (condition3) { return value3; }else { return value4; }}// Shorthand for the above functionfunction example() {return condition1 ? value1: condition2 ? value2: condition3 ? value3: value4;}
70、 freeze() 方法有什么作用?
freeze() 方法凍結(jié)一個對象。它使對象不可變。
凍結(jié)對象后,無法向其添加新屬性。
例如:
const item = { name: "test" };Object.freeze(item);item.name = "Something else"; // Error
71、如何獲取對象的鍵列表?
使用 Object.keys() 方法。
例如:
const student = {name: 'Mike',gender: 'male',age: 23};console.log(Object.keys(student));
["name", "gender", "age"]72、JavaScript 的原始數(shù)據(jù)類型是什么?
原始數(shù)據(jù)類型具有原始值。JavaScript 中有七種不同的原始數(shù)據(jù)類型:
string——單詞。例如“約翰”。
number — 數(shù)值。例如12。
boolean — 真或假。例如真。
null — 沒有值。例如讓 x = null;
undefined — 聲明變量但沒有值的類型。例如,當(dāng)以這種方式創(chuàng)建變量 x 時,讓 x; , x 變?yōu)槲炊x。
bigint — 表示大于 2^53-1 的整數(shù)的對象。例如 BigInt(121031393454720292)
symbol — 用于創(chuàng)建獨特符號的內(nèi)置對象。例如 let sym1 = Symbol(‘test’)
73、有哪些方法可以訪問對象的屬性?
共有三種訪問屬性的方法。
點符號。
例如:
obj.property方括號表示法。
例如:
obj["property"]表達式符號。
例如:
obj[expression]74、頁面加載后如何執(zhí)行JavaScript代碼?
你可以通過三種方式執(zhí)行此操作:
將屬性 window.onload 設(shè)置為在頁面加載后執(zhí)行的函數(shù):
window.onload = function ...document.onload = function ...<body onload="script();">75、什么是錯誤對象?
錯誤對象是一個內(nèi)置對象,如果發(fā)生錯誤,它會為你提供詳細(xì)的錯誤信息。
錯誤對象有兩個屬性:
name
message
例如,假設(shè) sayHi() 函數(shù)拋出錯誤。發(fā)生這種情況時,catch 塊會為你提供一個錯誤對象,例如,你可以將其打印到控制臺。
try {sayHi("Welcome");}catch(error) {console.log(error.name + "\n" + error.message);}
76、NoScript 標(biāo)簽有什么作用?
Noscript 標(biāo)簽用于檢測和響應(yīng)禁用 JavaScript 的瀏覽器。
你可以使用 noscript 標(biāo)簽來執(zhí)行一段通知用戶的代碼。
例如,你的 HTML 頁面可以有一個像這樣的 noscript 標(biāo)簽:
<script>document.write("Hello World!");</script><noscript>Your browser does not support JavaScript!</noscript>
77、 什么是入口控制循環(huán)?
在入口控制循環(huán)中,條件在進入循環(huán)體之前進行測試。
例如,for 循環(huán)和 while 循環(huán)就屬于這一類:
let nums = [1,2,3];for (let num of nums) {console.log(num);}
123
78、什么是出口控制循環(huán)?
在退出控制循環(huán)中,在循環(huán)結(jié)束時評估條件。這意味著無論條件為真還是假,循環(huán)體至少執(zhí)行一次。
例如,do-while 循環(huán)就屬于這一類:
const i = 0;do {console.log('The number is', i);} while (i !== 0);
The number is 079、什么是匿名函數(shù)?
匿名函數(shù)是沒有名字的函數(shù)。
匿名函數(shù)通常分配給變量名稱或用作回調(diào)函數(shù)。
這是一個帶有名稱供參考的函數(shù):
function example(params) {// do something}
const myFunction = function() {// do something};
[1, 2, 3].map(function(element) {// do something});
80、什么是迭代器?
迭代器協(xié)議使對象生成一系列值成為可能。
迭代器必須實現(xiàn) next() 方法來獲取序列中的下一個值。此方法返回一個對象
value - 迭代序列中的下一個值
done - 如果此值是序列中的最后一個,則為真。如果不是,那就是假的。
這是創(chuàng)建和使用迭代器的示例。這個函數(shù)實現(xiàn)了一個可以被 rangeIter(1,5) 調(diào)用的范圍迭代器,并打印值 1 2 3 4。
// define a function that returns an iteratorfunction rangeIter(start = 0, end = Infinity, step = 1) {let nextIndex = start;let count = 0;// create the actual iterator objectconst iterator = {// create the next() method that knows how to get the next value in the sequencenext: function() {let result;if (nextIndex < end) {// Return the value and set done 'false' because the iteration is not completedresult = { value: nextIndex, done: false }nextIndex += step;count++;return result;}// set done 'true' when the end has been reachedreturn { value: count, done: true }}};// return an iterator objectreturn iterator;}// Using the iteratorconst it = rangeIter(1, 5);let result = it.next();while (!result.done) { // prints 1 2 3 4console.log(result.value);result = it.next();}
81、什么是可迭代對象?
可迭代協(xié)議意味著一個對象可以被迭代,因此實現(xiàn)了迭代器協(xié)議(問題 80。)
換句話說,你可以在任何可迭代對象上使用 for...of 循環(huán)來循環(huán)遍歷它生成的值序列。
例如,Array 或 Map 在 JavaScript 中是可迭代的,但 Object 不是。
下面是一個在數(shù)組上應(yīng)用 for...of 循環(huán)的例子,它本質(zhì)上是可迭代的:
const nums = [1,2,3];for (let num of nums) {console.log(num);}
123
82、 什么是生成器?
生成器是迭代器的替代品。你可以編寫具有非連續(xù)執(zhí)行的迭代代碼。換句話說,可以暫停生成器函數(shù)的執(zhí)行。
生成器是使用 function* 語法定義的。它們不是返回值,而是產(chǎn)生值。
創(chuàng)建時,生成器不執(zhí)行其代碼。相反,它們返回一個 Generator 對象,它本質(zhì)上是一個迭代器。當(dāng)你對生成器對象調(diào)用 next() 時,它會運行代碼直到遇到 yield 語句,然后停止。
例如,這是一個與上面迭代器部分中的迭代器完全相同的生成器:
// Create a generator function that returns an iteratorfunction* rangeIter(start = 0, end = Infinity, step = 1) {let count = 0;for (let i = start; i < end; i += step) {count++;yield i;}return count;}// Create a generator objectconst it = rangeIter(1, 5);// Use the generator exactly how you'd use an iteratorlet result = it.next();while (!result.done) { // prints 1 2 3 4console.log(result.value);result = it.next();}
rangeIter 函數(shù)比迭代器示例中的 rangeIter 更容易閱讀。然而,兩者都做完全相同的事情。
83、什么是 for of 循環(huán)?
For...of 循環(huán)可用于在 JavaScript 中迭代可迭代對象。
例如,你可以使用 for...of 循環(huán)打印數(shù)組的內(nèi)容:
const nums = [1,2,3];for (const num of nums) {console.log(num);}
123
84、什么是nodejs?
Node.js 建立在 Chrome 的 JS 運行時之上。它是一個以可擴展方式構(gòu)建網(wǎng)絡(luò)應(yīng)用程序的平臺。
85、什么是事件循環(huán)?
事件循環(huán)是一個回調(diào)函數(shù)隊列。它處理所有異步回調(diào)。
當(dāng)異步函數(shù)執(zhí)行時,回調(diào)函數(shù)被推入隊列。JavaScript 引擎不會在異步任務(wù)完成之前觸發(fā)事件循環(huán)。
例如,事件循環(huán)的結(jié)構(gòu)可能如下所示:
while (queue.waitForMessage()) {queue.processNextMessage();}
86、什么是一元運算符?
一元 運算符+用于將變量轉(zhuǎn)換為數(shù)字。
如果變量無法轉(zhuǎn)換,則轉(zhuǎn)換為 NaN(這是數(shù)字的特殊情況,因此類型仍然是數(shù)字)。
例如:
let str = "10";let num = +str;console.log(typeof str, typeof num);let word = "Hello";let n = +word;console.log(typeof word, typeof n, n);
string, numberstring, number, NaN
87、如何對數(shù)組的元素進行排序?
使用 sort() 對數(shù)組的項進行排序。這不會創(chuàng)建新數(shù)組,而是“就地”對原始數(shù)組進行排序,即直接修改它。
let months = ["Adam", "Sam", "Jack", "Bill"];months.sort();console.log(months);
["Adam", "Bill", "Jack", "Sam"]88、什么是TypeScript ?
TypeScript 是帶有類型的 JavaScript。它是由 Microsoft 創(chuàng)建的 JavaScript 超集。
TypeScript 在普通 JavaScript 中添加了諸如可選類型、類、async/await 等類型。
這是 TypeScript 函數(shù)的一個簡單示例:
function greet(name: string): string {return "Hello, " + name;}console.log(greet("Michael"));
89、 JavaScript 中的構(gòu)造函數(shù)是什么?
構(gòu)造函數(shù)是用于創(chuàng)建和初始化類對象的方法。當(dāng)你從一個類中實例化一個新對象時,它就會被執(zhí)行。
例如:
class Student {constructor() {this.name = "Mike";}}let student = new Student();console.log(student.name);
Mike90、什么是ES6?
ES6 (ECMAScript 6) 是 JavaScript 編程語言的第六個版本。它于2015年6月發(fā)布。
91、什么是模板字面量?
模板文字允許你直接在字符串中嵌入表達式。
使用模板文字時,不要用引號聲明字符串,而是使用反引號 (`)。
要將變量或表達式嵌入到字符串中,需要在 ${} 之間添加
例如:
console.log(`This is the ${10 * 10}th time`)This is the 100th time92、如何在沒有第三個變量的情況下交換兩個變量?
使用解構(gòu)從數(shù)組中提取值。這也可用于在沒有第三個幫助程序的情況下交換兩個變量:
let a = 1;let b = 2;[a, b] = [b, a];console.log(a, b)
2 193、什么是 ArrayBuffer?
ArrayBuffer 是通用且固定長度的二進制數(shù)據(jù)緩沖區(qū)。
let buffer = new ArrayBuffer(16);console.log(buffer.byteLength)
16Math 對象從 Math 原型繼承屬性
數(shù)組對象從數(shù)組原型繼承屬性。
原型是對象的特征。它描述了與之相關(guān)的屬性。它充當(dāng)對象的藍圖。
function Fruit(name, weight) {this.name = name;this.weight = weight;}Fruit.prototype.description = "Yum!";
// Traditional functionvar sum = function(a,b){return a + b;}// Arrow Functionvar sum = (a,b) => a + b;
const student = { "name":"Mike", "id": 132123, "city": "New York"};console.dir(student);

<body oncontextmenu="return false;">function greet(name){console.log('Hello', name);}
function circleArea(radius) {return Math.PI * Math.pow(radius, 2);}
const PersonDetails = {name: "Matty",age: 42,married: false}const name = PersonDetails.name;const age = PersonDetails.age;const married = PersonDetails.married;console.log(name);console.log(age);console.log(married);
但是從 ES6 開始,你可以通過使用對象解構(gòu)用一行代碼來做到這一點:
const PersonDetails = {name: "Matty",age: 42,married: false}const {name, age, married} = PersonDetails;console.log(name);console.log(age);console.log(married);
結(jié)論
謝謝閱讀。我希望你喜歡它。
祝你面試或考試好運。
編程快樂!
PS:到這里,這100道面試題就已經(jīng)全部分享完畢了,希望對你有所幫助,同時也歡迎你在留言區(qū)跟我留言,告訴我,你還想學(xué)習(xí)那些方面的知識。
學(xué)習(xí)更多技能
請點擊下方公眾號
![]()
