我们接上篇内容《100 道 JavaScript 面试题及答案(上)》,今天我们开启下篇,把后面的50道题认真看完。
现在,我们就开始吧。
51. promises中的race method是什么意思?
Promise.race() 方法返回首先解决或拒绝的Promise。
让我们用一个例子来证明这一点,第二个promise 比第一个promise 更快地解决:
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 se
cond promise was faster
52. promise.all() 方法有什么作用?
Promise.all 是一个将一系列promise 作为输入的promise 。它在以下情况下得到解决:
要么所有的输入promise 都得到解决。
或者其中任何一个被拒绝。
例如,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()函数?
eval() 函数是计算字符串中的代码,要评估的字符串可以是表达式、变量、语句或语句序列。
例如:
console.log(eval(“5+10”));
输出:
15
54.什么是事件冒泡?
在事件冒泡中,事件通过在最内层元素上运行事件处理程序开始。然后它触发父母的事件处理程序,直到它到达最外层的元素。
查看此操作的最佳方法是创建一个 HTML 文档,在 divs 中包含 divs:
<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 警报,当单击该 div 时会触发该警报。
结果页面如下所示:
![100 道 JavaScript 面试题及答案(下)](http://www.webqdkf.com/wp-content/uploads/2023/04/04.png)
如果您现在单击内层,它会触发分配给该 div 的警报,并且会触发父 div 的警报。
55.什么是时间死区?
时间死区意味着变量无法访问,即使它已经在范围内。
让我们首先看一下当您尝试在未初始化的情况下将变量记录到控制台时会发生什么:
console.log(x);
var x = “Yay”;
输出:
undefined
您可能希望这会导致错误,但它会打印出 undefined。
发生这种情况是因为hoisting,这意味着所有声明都被移动到范围的顶部。由于hoisting,上面的代码在幕后表现如下:
var x;
console.log(x);
x = “Yay”;
这里 undefined 自动分配给顶部的变量,这使得在定义它之前使用它成为可能。
但是让我们看看当我们使用 let 而不是 var 做同样的事情时会发生什么:
console.log(x);
let x = 10;
输出:
error: Uncaught ReferenceError: Cannot access ‘x’ before initialization
发生这种情况是因为 let 的hoisting方式与 var 不同。当一个 let 变量被hoisting时,它不会变成未定义的。相反,它是不可访问的,或者在时间死区中,直到它被分配一个值。
56.什么是URI?
URI 或统一资源标识符是一组用于区分资源的字符,URI 允许互联网协议执行资源之间的操作。
URI 看起来像这样:
hello://example.com:8042/there?name=jack#sumthing
57. 什么是 DOM?
加载网页后,浏览器会为该页面创建一个 DOM。这赋予了 JavaScript 创建动态 HTML 的能力。
DOM 或文档对象模型充当 HTML 文档的 API,它定义了文档的结构,它还指定如何访问和修改文档。
58. 文档加载与 DOMContentLoaded?
DOMContentLoaded 事件在加载和解析 HTML 文档时触发,它不等待资产(例如样式表和图像)。
文档加载事件仅在加载整个页面(包括所有资产)后触发。
例如,下面是如何使用 DOMContentLoaded 在 DOM 完全加载时发出通知:
window.addEventListener(‘DOMContentLoaded’, (event) => {
console.log(‘DOM is now loaded!’);
});
这是一个示例,说明如何在加载特定页面时添加侦听器:
window.addEventListener(‘load’, (event) => {
console.log(‘The page is now loaded!’);
});
59. HTML 属性与 DOM 属性?
当您编写 HTML 时,您可以在 HTML 元素上定义属性。然后,当您使用浏览器打开该页面时,您的 HTML 代码将被解析。至此,一个DOM节点就创建好了。这个 DOM 节点对应于您刚刚编写的 HTML 文档。此 DOM 节点是一个具有属性的对象。
例如,这个 HTML 元素:
<input id=”my-input” type=”text” value=”Name:”>
具有三个属性,id,type,value。
当浏览器解析这个 HTML 元素时
它获取此输入字段并从中烘焙一个 HTMLInputElement 对象。
这个对象有accept、accesKey、align等几十个属性。
它还将一些原始的 HTML 属性变成了属性,例如 id 和 type。但是,例如,value 属性不引用 value 属性。
60.什么是同源策略?
同源策略是一种有价值的安全机制。它可以防止 JavaScript 越过域边界发出请求。
来源是指 URI 方案、主机名和端口号。同源策略使得一个页面上的脚本不可能访问另一个页面上的敏感数据。
61. JavaScript 是编译语言还是解释语言?
JavaScript 是一种解释型语言。
浏览器中的解释器读取 JavaScript 代码、解释每一行并运行它。
62. JavaScript 是区分大小写的语言吗?
JavaScript 是一种区分大小写的语言。
关键字、变量、函数名等需要大写一致。
为了演示,这段代码有效
let i = 1;
while(i < 2) {
console.log(i);
i++;
}
但这并没有,因为 while 被大写了,尽管它不应该大写。
let i = 1;
WHILE(i < 2) {
console.log(i);
i++;
}
63. JavaScript 中有多少个线程?
JavaScript 使用单线程。它不允许编写解释器可以在多个线程或进程中并行运行的代码。
这意味着它按顺序执行代码并且必须执行完一段代码才能移动到下一段代码。
当您在网页上显示警报时,就是一个很好的例子。警报弹出后,您无法与页面交互,直到警报关闭。
alert(“Hello there!”);
64.“break”语句有什么作用?
break语句跳出循环,继续执行循环外的代码。
例如,此循环在遇到数字 5 后终止:
for (var i = 0; i < 100; i++) {
if (i === 5) {
break;
}
console.log(‘Number is ‘, i);
}console.log(‘Yay’);
Number is 0
Number is 1
Number is 2
Number is 3
Number is 4
Yay
65. “continue”语句的作用是什么?
continue 语句跳过一轮循环。
例如,此循环会跳过数字 2 和 3:
for (var i = 0; i < 5; i++) {
if (i === 2 || i === 3) {
continue;
}
console.log(‘Number is ‘, i);
}
输出:
0
1
4
66.什么是正则表达式?
正则表达式,也称为 regex 或 regexp,是一组构成搜索模式的字符。它是一种模式匹配工具,常用于 JavaScript 和其他编程语言。
例如,让我们使用正则表达式从字符串中查找任意数字:
var regex = /\d+/g;
var string = “You have 100 seconds time to run”;
var matches = string.match(regex);
console.log(matches);
输出是所有匹配项的数组:
[100]
例如,正则表达式可用于在大型文本文件中搜索电子邮件或电话号码。
67. 调试代码时断点的作用是什么?
断点允许您在 JavaScript 代码中查找错误。
当执行调试器语句并出现调试器窗口时,您可以在代码中设置断点。
在断点处,JavaScript 停止执行并让您检查值和范围以解决可能的问题。
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-else
age < 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 function
function example() {
return condition1 ? value1
: condition2 ? value2
: condition3 ? value3
: value4;
}
70. freeze() 方法有什么作用?
freeze() 方法冻结一个对象。它使对象不可变。
冻结对象后,无法向其添加新属性。
例如:
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 的原始数据类型有哪些?
原始数据类型具有原始值。JavaScript 中有七种不同的原始数据类型:
string——单词。例如,“John”。
number— 数值。例如, 12。
boolean——真或假。例如,true。
null — 没有值。例如,let x = null;
undefined——声明变量但没有值的类型。例如,当以这种方式创建变量 x 时,let x; , x 变得undefined。
bigint — 用于表示大于 2^53–1 的整数的对象。例如 BigInt(121031393454720292)
symbol — 用于创建独特符号的内置对象。例如,let sym1 = Symbol(‘test’)
73.有哪些方法可以访问对象的属性?
可以通过三种方式访问属性。
点符号。
例如:
obj.property
方括号表示法。
例如:
obj[“property”]
表达式符号。
例如:
obj[expression]
74. 如何在页面加载后执行 JavaScript 代码?
您可以通过三种方式执行此操作:
将属性 window.onload 设置为在页面加载后执行的函数:
window.onload = function …
将属性 document.onload 设置为在页面加载后执行的函数:
document.onload = function …
将 HTML 属性的 onload 属性设置为 JS 函数:
<body onload=”script();”>
75.什么是错误对象?
错误对象是一个内置对象,如果发生错误,它会为您提供详细的错误信息。
错误对象有两个属性:
nema
message
例如,假设 sayHi() 函数抛出错误。发生这种情况时,catch 块会为您提供一个错误对象,您可以将其打印到控制台。
try {
sayHi(“Welcome”);
}
catch(error) {
console.log(error.name + “\n” + error.message);
}
76.NoScript标签有什么作用?
Noscript 标签用于检测和响应禁用 JavaScript 的浏览器。
您可以使用 noscript 标签来执行一段通知用户的代码。
例如,您的 HTML 页面可以有一个像这样的 noscript 标签:
<script>
document.write(“Hello World!”);
</script><noscript>
Your browser does not support JavaScript!
</noscript>
77. 什么是入口控制循环?
在入口控制循环中,在进入循环体之前测试条件。
例如,for 循环和 while 循环就属于这一类:
let nums = [1,2,3];
for (let num of nums) {
console.log(num);
}
输出:
1
2
3
78. 什么是退出控制循环?
在退出控制循环中,在循环结束时评估条件。这意味着无论条件为真还是假,循环体至少执行一次。
例如,do-while 循环就属于这一类:
const i = 0;
do {
console.log(‘The number is’, i);
} while (i !== 0);
输出:
The number is 0
79.什么是匿名函数?
匿名函数是没有名字的函数。
匿名函数通常分配给变量名或用作回调函数。
这是一个带有名称的函数供参考:
function example(params) {
// do something
}
这是一个分配给变量的匿名函数:
const myFunction = function() {
// do something
};
这是一个用作回调的匿名函数:
[1, 2, 3].map(function(element) {
// do something
});
80.什么是迭代器?
迭代器协议使对象可以生成一系列值。
迭代器必须实现 next() 方法以获取序列中的下一个值。这个方法返回一个对象
value——迭代序列中的下一个值
done——如果这个值是序列中的最后一个,则为真。如果不是,那就是false。
下面是创建和使用迭代器的示例。该函数实现了一个范围迭代器,可以由 rangeIter(1,5) 调用,并打印值 1 2 3 4。
// define a function that returns an iterator
function rangeIter(start = 0, end = Infinity, step = 1) {
let nextIndex = start;
let count = 0;
// create the actual iterator object
const iterator = {
// create the next() method that knows how to get the next value in the sequence
next: function() {
let result;
if (nextIndex < end) {
// Return the value and set done ‘false’ because the iteration is not completed
result = { value: nextIndex, done: false }
nextIndex += step;
count++;
return result;
}
// set done ‘true’ when the end has been reached
return { value: count, done: true }
}
};
// return an iterator object
return iterator;
}// Using the iterator
const it = rangeIter(1, 5);let result = it.next();
while (!result.done) { // prints 1 2 3 4
console.log(result.value);
result = it.next();
}
81. 什么是可迭代对象?
可迭代协议意味着一个对象可以被迭代,因此实现了迭代器协议(问题 80)。
换句话说,您可以在任何可迭代对象上使用 for…of 循环来遍历它生成的值序列。
例如,Array 或 Map 在 JavaScript 中是可迭代的,但 Object 不是。
下面是一个在数组上应用 for…of 循环的示例,该数组本质上是可迭代的:
const nums = [1,2,3];
for (let num of nums) {
console.log(num);
}
输出:
1
2
3
82.什么是生成器?
生成器是迭代器的替代品。您可以编写非连续执行的迭代代码。换句话说,可以暂停生成器函数的执行。
生成器是使用 function* 语法定义的。它们不是返回值,而是产生值。
创建时,生成器不执行它们的代码。相反,它们返回一个 Generator 对象,它本质上是一个迭代器。当您在生成器对象上调用 next() 时,它会运行代码,直到遇到 yield 语句,然后停止。
例如,这里有一个生成器,其功能与上面迭代器部分中的迭代器完全相同:
// Create a generator function that returns an iterator
function* 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 object
const it = rangeIter(1, 5);// Use the generator exactly how you’d use an iterator
let result = it.next();
while (!result.done) { // prints 1 2 3 4
console.log(result.value);
result = it.next();
}
rangeIter 函数比迭代器示例中的 rangeIter 更容易阅读。然而两者都做完全相同的事情。
83. 什么是 for of 循环?
For…of 循环可用于迭代 JavaScript 中的可迭代对象。
例如,您可以使用 for…of 循环打印数组的内容:
const nums = [1,2,3];
for (const num of nums) {
console.log(num);
}
输出:
1
2
3
84.什么是nodejs?
Node.js 建立在 Chrome 的 JS 运行时之上。它是一个以可扩展方式构建网络应用程序的平台。
85.什么是事件循环?
事件循环是一个回调函数队列。它处理所有异步回调。
当一个异步函数执行时,一个回调函数被推入队列。在异步任务完成之前,JavaScript 引擎不会触发事件循环。
例如,事件循环的结构可能如下所示:
while (queue.waitForMessage()) {
queue.processNextMessage();
}
86.什么是一元运算符?
一元 + 运算符用于将变量转换为数字。
如果变量无法转换,则将其转换为 NaN(这是数字的特殊情况,因此类型仍然是数字)。
例如:
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, number
string, number, NaN
87. 如何对数组的元素进行排序?
使用 sort() 对数组的项目进行排序。这不会创建一个新数组,而是“就地”对原始数组进行排序,即直接修改它。
let months = [“Adam”, “Sam”, “Jack”, “Bill”];
months.sort();
console.log(months);
输出:
[“Adam”, “Bill”, “Jack”, “Sam”]
88. 什么是 TypeScript?
TypeScript 是带有类型的 JavaScript。它是 Microsoft 创建的 JavaScript 超集。
TypeScript 将可选类型、类、async/await 等类型添加到纯 JavaScript 中。
这是 TypeScript 函数的一个简单示例:
function greet(name: string): string {
return “Hello, ” + name;
}console.log(greet(“Michael”));
89. JavaScript 中的构造函数是什么?
构造函数是用于创建和初始化类对象的方法。当您从一个类中实例化一个新对象时,它会被执行。
例如:
class Student {
constructor() {
this.name = “Mike”;
}
}let student = new Student();
console.log(student.name);
输出:
Mike
90.什么是ES6?
ES6(ECMAScript 6)是 JavaScript 编程语言的第六版。它于 2015 年 6 月发布。
91.什么是模板文字?
模板文字允许您将表达式直接嵌入到字符串中。
使用模板文字时,不要用引号声明字符串,而是使用反引号 (`)。
要将变量或表达式嵌入到字符串中,您需要将其添加到 ${} 之间
例如:
console.log(`This is the ${10 * 10}th time`)
输出:
This is the 100th time
92. 如果没有第三个变量,如何交换两个变量?
使用解构从数组中分离值。这也可以用于在没有第三个助手的情况下交换两个变量:
let a = 1;
let b = 2;
[a, b] = [b, a];
console.log(a, b)
输出:
2 1
93. 什么是 ArrayBuffer?
ArrayBuffer 是通用的固定长度二进制数据缓冲区。
let buffer = new ArrayBuffer(16);
console.log(buffer.byteLength)
输出:
16
94.什么是原型?
所有 JavaScript 对象都从原型继承属性。
例如:
Math 对象从 Math 原型继承属性
Array 对象从 Array 原型继承属性。
原型是对象的特征。它描述了与之关联的属性。它充当对象的蓝图。
例如,您可以访问对象的原型以向对象构造函数添加新属性,例如:
function Fruit(name, weight) {
this.name = name;
this.weight = weight;
}
Fruit.prototype.description = “Yum!”;
95.什么是箭头函数?
箭头函数提供了一种在 JavaScript 中创建函数的简写方式。
您只能在函数表达式中使用箭头函数。
这是常规函数和箭头函数的比较:
// Traditional function
var sum = function(a,b){
return a + b;
}// Arrow Function
var sum = (a,b) => a + b;
箭头函数声明时不使用 function 关键字。
如果只有一个(返回)表达式,则不需要使用 return 关键字。
在上面,花括号也不见了。这只有在箭头函数只包含一个表达式时才有可能。如果还有更多,则需要在箭头后添加花括号。
96. dir()方法有什么用?
console.dir() 将 JavaScript 对象的属性的交互式列表显示为 JSON。
例如:
const student = { “name”:”Mike”, “id”: 132123, “city”: “New York”};
console.dir(student);
在控制台中产生以下交互式列表:
97. 如何禁用网页上的右键单击?
您可以通过从 body 元素的 oncontextmenu 属性返回 false 来禁用网页上的右键单击。
<body oncontextmenu=”return false;”>
98.什么是一元函数?
一元函数是只接受一个参数的函数。
例如:
function greet(name){
console.log(‘Hello’, name);
}
99.什么是纯函数?
纯函数是一种函数,无论何时何地被调用,它都以相同的参数返回相同的结果。如果一个函数不依赖于程序执行期间的状态或数据更改,那么它就是纯函数。
例如,计算圆面积的函数是纯函数:
function circleArea(radius) {
return Math.PI * Math.pow(radius, 2);
}
100.什么是对象解构?
对象解构是一种从对象(或数组)中提取属性的方法。
在 ES6 之前,你需要这样做来提取对象的属性:
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 以来,您可以通过利用对象解构来使用一行代码来完成此操作:
const PersonDetails = {
name: “Matty”,
age: 42,
married: false
}const {name, age, married} = PersonDetails;
console.log(name);
console.log(age);
console.log(married);
总结
到这里,我想与你分享的100道JavaScript前端面试题就全部结束了,如果你还有什么问题,或者想看更多其他方面的面试题,请在留言区告诉我,我会逐一安排上。
在此,非常感谢您的阅读,如果您对前端技术感兴趣的话,也欢迎您关注我,我会不定期的分享关于前端领域的知识技能与资讯。
最后,希望这些知识能够帮助到您。
如果您还想阅读更多关于面试题相关文章,可以到公众号的菜单栏【前端开发】-【面试题】进行阅读更多相关文章内容。
或者点击【前端面试题】即可查看所有面试题文章内容。