前端面试必备 | JavaScript篇(P61-90)
61. 什么是事件对象?如何获取事件对象的属性?
事件对象是JavaScript中用于存储和传递事件相关信息的对象。当事件发生时,浏览器会自动创建一个事件对象,并将其作为参数传递给事件处理函数。
要获取事件对象的属性,可以在事件处理函数中使用event参数来访问事件对象的属性。根据不同的事件类型,事件对象可能会具有不同的属性。一些常见的事件对象属性如下:
event.target:获取事件发生的元素的引用。event.type:获取事件类型。event.clientX和event.clientY:获取鼠标指针在屏幕上的坐标。event.keyCode:获取按下的键盘按键的键码。event.preventDefault():阻止事件的默认行为。event.stopPropagation():停止事件的冒泡传播。
通过使用这些属性,你可以获取事件对象的相关信息,并根据需要进行逻辑处理。
62. JavaScript中的正则表达式是什么?如何使用正则表达式?
正则表达式是一种模式匹配的工具,用于在文本中搜索和匹配特定的字符串模式。它使用一组特定的字符和语法规则,可以用来验证、搜索、替换和提取字符串。
要在JavaScript中使用正则表达式,可以使用RegExp对象或者使用正则表达式字面量的方式创建一个正则表达式对象。例如,下面是两种创建正则表达式对象的方式:
使用RegExp对象的构造函数:
var regex = new RegExp("pattern");
使用正则表达式字面量:
var regex = /pattern/;
在使用正则表达式时,可以使用各种正则表达式的方法和属性对文本进行匹配和处理。 一些常用的方法和属性有:
test():用于检查字符串中是否存在与正则表达式匹配的内容,并返回布尔值。exec():用于在字符串中执行正则表达式的搜索,并返回第一个匹配的结果。match():用于在字符串中查找与正则表达式匹配的内容,并返回一个数组。replace():用于在字符串中查找与正则表达式匹配的内容,并进行替换。search():用于在字符串中查找与正则表达式匹配的内容,并返回匹配的位置。split():用于将字符串根据正则表达式匹配的内容分割成多个子字符串。
通过使用这些方法和属性,你可以根据需要来使用正则表达式对文本进行各种操作和处理。
63. 如何复制一个数组或对象?
要复制一个数组或对象,可以使用不同的方法。下面是几种常见的复制数组或对象的方法:
- 使用
Array.from()方法(用于复制数组)或Object.assign()方法(用于复制对象):
const originalArray = [1, 2, 3];
const copiedArray = Array.from(originalArray);
// 或者: const copiedArray = Object.assign([], originalArray);
const originalObject = { name: 'John', age: 25 };
const copiedObject = Object.assign({}, originalObject);
- 使用扩展运算符(
...):
const originalArray = [1, 2, 3];
const copiedArray = [...originalArray];
const originalObject = { name: 'John', age: 25 };
const copiedObject = { ...originalObject };
- 使用
JSON.parse()和JSON.stringify()(适用于复制纯粹的数据对象,无法复制函数等特殊属性):
const originalArray = [1, 2, 3];
const copiedArray = JSON.parse(JSON.stringify(originalArray));
const originalObject = { name: 'John', age: 25 };
const copiedObject = JSON.parse(JSON.stringify(originalObject));
请注意,这些方法只会复制原始数组或对象的基本结构,对于对象中的复杂数据类型(如嵌套数组或对象,函数等),仅会复制引用。如果需要深拷贝包括复杂数据类型在内的数组或对象,可以使用专门的库,如lodash的cloneDeep方法。
64. 说下this/cal/apply/bind
this、call、apply 和 bind 是 JavaScript 语言中与函数调用相关的概念和方法。
-
this: this 是函数中的一个特殊对象,它指向调用该函数的上下文对象。具体指向哪个对象取决于函数是如何调用的。在全局作用域中,this 指向全局对象(浏览器环境中是 window 对象)。在对象方法中,this 指向调用该方法的对象。在构造函数中,this 指向新创建的对象。通过使用箭头函数,this 会捕获其外层作用域的 this 值,因此不会被改变。
-
call 和 apply: call 和 apply 是函数的两个方法,用于显式地指定函数中的 this 值,并立即调用该函数。两者的用法类似,区别在于传递参数的方式不同。call 方法接受一个参数列表,而 apply 方法接受一个参数数组。
function sayHi() {
console.log(`Hi, ${this.name}`);
}
const person = {
name: 'John'
};
sayHi.call(person); // 输出:Hi, John
sayHi.apply(person); // 输出:Hi, John
- bind: bind 方法返回一个新的函数,并将其中的 this 值固定为指定的对象。返回的函数可以稍后调用,并具有绑定的 this 值,并且可以传递参数。
function sayHi() {
console.log(`Hi, ${this.name}`);
}
const person = {
name: 'John'
};
const sayHiToPerson = sayHi.bind(person);
sayHiToPerson(); // 输出:Hi, John
这些概念和方法可以让我们更灵活地使用函数,并在不同的上下文中执行代码。
65. JavaScript中如何判断一个变量是否是数字类型?
在 JavaScript 中,可以使用 typeof 运算符来判断一个变量是否是数字类型。typeof 运算符返回一个字符串,表示操作数的数据类型。
typeof 变量 === 'number'
例如:
const num = 42;
console.log(typeof num === 'number'); // 输出 true
const str = 'hello';
console.log(typeof str === 'number'); // 输出 false
const bool = true;
console.log(typeof bool === 'number'); // 输出 false
另一种方法是使用 isNaN() 函数来判断一个变量是否是 NaN(非数字)。
isNaN(变量)
例如:
console.log(isNaN('hello')); // 输出 true(因为 'hello' 不是一个有效的数字)
console.log(isNaN(42)); // 输出 false(因为 42 是一个有效的数字)
console.log(isNaN(true)); // 输出 false(因为 true 被转换为数字 1)
需要注意的是,isNaN() 函数对于非数字值进行了隐式转换。因此,如果需要严格判断一个变量是否是数字类型,最好使用 typeof 运算符。
66. JavaScript中的扩展运算符(Spread Operator)是什么?有什么作用?
JavaScript中的扩展运算符(Spread Operator)是一种语法,用于将一个可迭代对象(如数组或字符串)展开为逗号分隔的一系列值。
它的作用是使得我们能够方便地将一个可迭代对象中的元素复制到另一个数组或函数调用的参数列表中。
使用扩展运算符,我们可以在数组字面量或函数调用中使用三个连续的点(...)来展开一个可迭代对象。例如:
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]
function sum(a, b, c) {
return a + b + c;
}
const numbers = [1, 2, 3];
console.log(sum(...numbers)); // 6
在数组字面量中,扩展运算符可以方便地将一个数组的元素复制到另一个数组中。在函数调用中,扩展运算符可以将一个数组的元素传递给函数作为参数。它还可以与其他元素一起使用,灵活地构建新的数组或参数列表。
67. 什么是事件监听器(Event Listener)?
事件监听器(Event Listener)是一种用于在特定事件发生时执行特定代码的机制。在 JavaScript 中,可以通过添加事件监听器来注册对特定事件的响应。
事件监听器由两部分组成:事件目标和事件处理函数。事件目标是指需要监听事件的对象,而事件处理函数是在事件触发时要执行的代码块。
使用事件监听器的基本步骤如下:
- 选择要监听事件的元素或对象。
- 使用addEventListener()函数或对象的on事件属性来注册事件监听器。指定事件类型和要执行的处理函数。
- 当事件发生时,事件目标会自动调用注册的事件处理函数。
例如,可以为按钮添加点击事件监听器,当按钮被点击时执行特定操作。下面是一个示例:
// 选择按钮元素
const button = document.querySelector('#myButton');
// 注册点击事件监听器
button.addEventListener('click', function() {
console.log('按钮被点击了!');
});
在上述示例中,当按钮被点击时,事件处理函数中的代码将被执行,输出“按钮被点击了!”到控制台。
通过使用事件监听器,可以实现对各种事件(如点击、鼠标移动、键盘按下等)的响应,并执行相应的操作。
68. 如何在JavaScript中处理同步和异步代码?
在 JavaScript 中,可以使用不同的方式来处理同步和异步代码。
对于同步代码,JavaScript 是按顺序执行的,它会等待前一个操作完成后再执行下一个操作。这意味着,如果存在某个操作需要较长时间才能完成,那么整个代码的执行会被阻塞,直到该操作完成。
而对于异步代码,JavaScript 使用回调函数、Promise、async/await 等机制来处理。这些机制允许在进行耗时操作(例如网络请求、文件读取等)时,不会阻塞代码的执行,而是通过异步的方式进行处理。
-
回调函数(Callback):可以通过将一个函数作为参数传递给另一个函数,在特定的事件发生时调用回调函数。例如,在 AJAX 请求完成时执行回调函数来处理响应数据。
-
Promise:Promise 是一个表示异步操作最终完成或失败的对象。它可以用于以更清晰的方式编写异步代码,通过链式调用 .then() 和 .catch() 方法来处理操作的结果。
-
async/await:async/await 是 ES2017 引入的一种用于处理异步代码的方式。通过使用 async 关键字来定义一个异步函数,然后在其中使用 await 关键字来等待一个 Promise 的解决。这使得异步代码看起来更像同步代码,提高了代码的可读性。
无论使用哪种方式处理异步代码,它们都旨在避免阻塞代码执行,并且提供了更加可读和易于理解的方式来处理异步操作。
69. JavaScript中的递归函数是什么?如何使用递归函数?
在 JavaScript 中,递归函数是指在函数体内调用自身的函数。递归函数通常用于解决需要重复执行相同步骤的问题。
要使用递归函数,需要考虑两个方面:
- 基本情况(Base Case):确定一个或多个简单情况,可以在这些情况下直接返回结果,而无需进一步调用递归函数。
- 递归情况(Recursive Case):将问题分解为一个或多个更小的子问题,并通过调用递归函数来解决这些子问题。
下面是一个使用递归函数计算阶乘的例子:
function factorial(n) {
// 基本情况:当 n 等于 0 或 1 时,直接返回 1
if (n === 0 || n === 1) {
return 1;
}
// 递归情况:调用递归函数计算 n-1 的阶乘,并将结果与 n 相乘
return n * factorial(n - 1);
}
console.log(factorial(5)); // 输出 120
在上面的例子中,递归函数 factorial() 通过将原始问题(计算 n 的阶乘)分解为更小的子问题(计算 n-1 的阶乘),最终得到结果。请注意,在编写递归函数时,确保存在基本情况,以避免无限递归的问题。
70. 如何获取当前页面的URL信息?
您可以使用 JavaScript 的 window.location 对象来获取当前页面的 URL 信息。具体来说,window.location 对象包含了一系列属性,其中最常用的是 href 属性,它返回当前页面的完整 URL。
以下是一个示例代码:
var currentURL = window.location.href;
console.log("当前页面的URL是:" + currentURL);
当您运行这段代码时,浏览器会将当前页面的 URL 输出到控制台。
71. JavaScript中的getElementById和querySelector有什么区别?
getElementById 和 querySelector 都是 JavaScript 中用于选择 DOM 元素的方法,但它们之间有一些区别。
getElementById 是 Document 对象的方法,用于通过元素的 id 属性获取一个 DOM 元素。它接受一个字符串作为参数,该字符串是元素的 id 值,如果找到匹配的元素,则返回该元素。如果没有找到匹配的元素,则返回 null。此方法是非常高效的,因为通过元素的 id 值进行查找是非常快速的。
以下是使用 getElementById 的示例代码:
var element = document.getElementById("myElement");
querySelector 是 Document 对象和 Element 对象的方法,用于通过 CSS 选择器选择一个 DOM 元素。它接受一个字符串作为参数,该字符串是一个合法的 CSS 选择器,用于描述要选择的元素的属性。它返回匹配选择器的第一个元素。如果没有找到匹配的元素,则返回 null。
以下是使用 querySelector 的示例代码:
var element = document.querySelector(".myClass");
需要注意的是,querySelector 方法返回的是单个元素(如果有多个匹配,也只返回第一个匹配的元素),而 getElementById 只能返回一个元素(因为 id 值在文档中是唯一的)。
除了这些区别之外,querySelector 还具有更强大的功能,可以选择任意 CSS 选择器,而不仅仅是通过 id 进行选择。因此,如果您需要更灵活的元素选择功能,可以使用 querySelector。
72. 什么是事件对象的冒泡和捕获阶段
在 JavaScript 中,事件对象的冒泡和捕获阶段是描述事件传播过程中不同阶段的概念。
冒泡阶段(Bubble phase)是指事件从最深层次的目标元素开始,逐级向上传播到更高层次的父元素,直至传播到文档的根节点。换句话说,事件首先触发目标元素上的事件处理程序,然后逐级向上触发祖先元素上的事件处理程序。
捕获阶段(Capture phase)则是事件从文档根节点开始,逐级向下传播到最深层次的目标元素。在捕获阶段,事件会依次触发从父元素到子元素的事件处理程序。
通过在添加事件监听器时传递第三个参数为 true,可以将事件处理程序绑定到捕获阶段。如果将第三个参数设置为 false 或省略,事件处理程序将默认绑定到冒泡阶段。
以下是一个示例:
var element = document.getElementById("myElement");
element.addEventListener("click", function() {
console.log("冒泡阶段");
});
element.addEventListener("click", function() {
console.log("捕获阶段");
}, true);
在这个示例中,当点击 myElement 元素时,首先会触发捕获阶段的事件处理程序,然后触发冒泡阶段的事件处理程序。
需要注意的是,默认情况下,大多数事件处理程序在冒泡阶段被触发。但是,有一些特定的事件(比如 focus 和 blur)只能在冒泡阶段触发,而不会在捕获阶段触发。
了解事件对象的冒泡和捕获阶段可以帮助您更好地理解事件处理过程,并在需要时选择合适的阶段来处理事件。
73. 什么是JavaScript的异步编程?
JavaScript的异步编程是一种编程模式,用于处理非阻塞的、可能耗时的操作,例如网络请求、文件读写等。在传统的同步编程中,代码按照顺序执行,每一行代码必须等待前一行代码完成才能执行。
异步编程允许同时执行多个任务,并在任务完成后处理结果。它通过使用回调函数、Promise、async/await等机制来实现。
常见的异步编程模式有:
- 回调函数(Callback):通过将一个函数作为参数传递给异步操作,在操作完成后调用回调函数来处理结果。
function fetchData(callback) {
// 异步操作
setTimeout(() => {
const data = "Data from async operation";
callback(data); // 调用回调函数处理结果
}, 1000);
}
fetchData((data) => {
console.log(dat
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
前端面试必备知识点:HTML和CSS、JS(变量/数据类型/操作符/条件语句/循环;面向对象编程/函数/闭包/异步编程/ES6)、DOM操作、HTTP和网络请求、前端框架、前端工具和构建流程、浏览器和性能优化、跨浏览器兼容性、前端安全、数据结构和算法、移动端开发技术、响应式设计、测试和调试技巧、性能监测等。准备面试时,建议阅读相关的技术书籍、参与项目实践、刷题和练习,以深化和巩固你的知识。
