你有必要知道的25个JavaScript面试题

下面是详细讲解“你有必要知道的25个JavaScript面试题”的完整攻略。

介绍

在面试过程中,JavaScript是一个非常重要的方面,掌握常见的JavaScript面试题可以帮助我们更好地准备面试。这里整理了25个常见的JavaScript面试题供大家参考。

问题列表

1. typeof null 返回什么?

typeof null 返回 "object"。请注意,这是JavaScript中一个已知的错误。

2. 如何将变量从一个文件导出并在另一个文件中使用?

一个常见的方式是使用 export 关键字将变量或函数导出,并使用 import 关键字在另一个文件中导入并使用它们。例如:

// 导出变量
export const name = "Jenny";
// 导出函数
export function add(a, b) {
  return a + b;
}

在另一个文件中使用导入:

// 导入变量和函数
import { name, add } from "./example.js";
console.log(name); // 输出 Jenny
console.log(add(2, 5)); // 输出 7

3. 什么是闭包?

闭包是指一个函数能够访问并操作其外部函数的变量。这是由于JavaScript的词法作用域和函数可以在其定义的作用域之外执行的特性所导致的。

function greet(name) {
  let message = `Hello, ${name}!`;

  function getMessage() {
    return message;
  }

  return getMessage;
}

const greeting = greet("Jenny");
console.log(greeting()); // 输出 Hello, Jenny!

这里,函数 greet 返回了 getMessage 函数,它可以访问外部函数 greet 中的变量 message

4. undefinednull 的区别是什么?

undefined 表示一个变量未赋值或未定义。null 表示一个变量的值为 null,即空对象引用。在布尔上下文中,它们都被认为是假值。

5. JavaScript 中有哪些类型?

JavaScript 中有六种类型:undefinednullstringnumberbooleanobject。ES6 中新增了一种类型,Symbol

6. 如何检查一个变量的类型?

可以使用 typeof 操作符来检查一个变量的类型:

const x = "Hello, world!";
console.log(typeof x); // 输出 string

7. 如何判断一个变量是否是数组?

可以使用 Array.isArray() 方法来判断一个变量是否是数组:

const arr = [1, 2, 3];
console.log(Array.isArray(arr)); // 输出 true

8. 什么是作用域?

作用域是指变量、函数和对象在代码中可访问的范围。JavaScript 有三种类型的作用域——全局作用域、函数作用域和块级作用域。

9. 什么是变量提升?

变量提升是指在 JavaScript 中,变量和函数声明的声明部分会被提升到当前作用域的顶部。这意味着在变量或函数被声明之前访问它们时,它们已经被初始化为 undefined

console.log(name); // 输出 undefined
var name = "Jenny";

10. 什么是事件冒泡?

事件冒泡是指在事件被触发后,它的父元素将依次接收该事件。

<div class="box">
  <button>Click me!</button>
</div>
const button = document.querySelector("button");
const box = document.querySelector(".box");

button.addEventListener("click", () => {
  console.log("Button clicked");
});

box.addEventListener("click", () => {
  console.log("Box clicked");
});

在上面的代码中,当点击按钮时,将会依次触发 button 元素和 box 元素上的单击事件,因此控制台将输出以下两行内容:

Button clicked
Box clicked

11. 什么是事件委托?

事件委托是指将事件处理程序添加到父元素,而不是将它们添加到子元素中,以避免在子元素数目很多的情况下产生垃圾代码。

<ul>
  <li>Apple</li>
  <li>Banana</li>
  <li>Orange</li>
</ul>
const list = document.querySelector("ul");

list.addEventListener("click", event => {
  if (event.target.tagName === "LI") {
    console.log(event.target.textContent);
  }
});

在上面的代码中,单击每个 <li> 元素时,将输出相应元素的文本内容。

12. 什么是深拷贝和浅拷贝?

浅拷贝是指将一个对象的引用复制到另一个对象中,而不是复制对象本身。因此,如果一个对象被更改,另一个对象也将被更改。

深拷贝是指将一个对象的副本复制到另一个对象中,而不是复制对象本身。因此,即使一个对象被更改,另一个对象也不会受到影响。

// 浅拷贝实例
const obj1 = { name: "Jenny", age: 23 };
const obj2 = obj1;

obj2.name = "Lily";
console.log(obj1.name); // 输出 Lily

// 深拷贝实例
const obj3 = { name: "Jenny", age: 23 };
const obj4 = JSON.parse(JSON.stringify(obj3));

obj4.name = "Lily";
console.log(obj3.name); // 输出 Jenny

13. 什么是回调函数?

回调函数是指一个函数作为另一个函数的参数,并在该函数执行完毕后被调用。

function greet(callback) {
  console.log("Hello, world!");
  callback();
}

greet(() => console.log("Nice to meet you!"));

在上面的代码中,greet 函数接受一个回调函数作为参数,并在输出 Hello, world! 后调用该回调函数。

14. 什么是 Promise?

Promise 是一种异步编程模式,它允许我们在代码执行完毕前处理异步操作的结果。

const promise = new Promise((resolve, reject) => {
  const request = new XMLHttpRequest();

  request.onreadystatechange = () => {
    if (request.readyState === 4 && request.status === 200) {
      resolve(request.responseText);
    } else if (request.readyState === 4) {
      reject("An error occurred");
    }
  };

  request.open("GET", "https://jsonplaceholder.typicode.com/todos/1");
  request.send();
});

promise.then(response => console.log(response)).catch(error => console.log(error));

在上面的代码中,Promise 的构造函数接受一个函数,该函数将使用异步操作并为异步操作提供一个 resolve 和一个 reject 参数。我们可以使用 thencatch 方法分别处理异步操作的结果。

15. 什么是闭包?

闭包是指一个函数能够访问并操作其外部函数的变量。这是由于JavaScript的词法作用域和函数可以在其定义的作用域之外执行的特性所导致的。

function greet(name) {
  let message = `Hello, ${name}!`;

  function getMessage() {
    return message;
  }

  return getMessage;
}

const greeting = greet("Jenny");
console.log(greeting()); // 输出 Hello, Jenny!

16. 什么是 JavaScript 中的 this 关键字?

this 关键字是指当前正在执行的函数所属的对象。如果函数被作为对象的方法调用,则 this 指向该对象。否则,它指向全局对象。

const person = {
  name: "Jenny",
  greet() {
    console.log(`Hello, my name is ${this.name}!`);
  }
};

person.greet(); // 输出 Hello, my name is Jenny!

在上面的代码中,当 greet 方法被调用时,this 指向 person 对象。

17. 如何取消 Promise?

可以使用 Promise.race() 方法创建一个新的 Promise,该 Promise 将与原始 Promise 竞争,并在其中一个 Promise 解决或拒绝时解决或拒绝。

const promise1 = new Promise(resolve => setTimeout(resolve, 3000));
const promise2 = new Promise((resolve, reject) =>
  setTimeout(() => reject("Timed out"), 5000)
);

Promise.race([promise1, promise2])
  .then(() => console.log("Promise resolved"))
  .catch(error => console.log(error)); // 输出 Timed out

在上面的代码中,两个 Promise 将竞争,并在 promise2 超时时拒绝。Promise.race() 将处理第一个解决或拒绝的 Promise。

18. JavaScript 中的防抖和节流是什么?

防抖和节流都是一些处理 JavaScript 事件性能问题的技术。

防抖是指在触发事件后等待一段时间再执行处理程序,如果在等待时间内再次触发该事件,则重新开始计时。这是为了避免处理程序被过度调用的问题。

function debounce(func, delay) {
  let timeout;

  return function() {
    clearTimeout(timeout);

    timeout = setTimeout(() => {
      func.apply(this, arguments);
    }, delay);
  };
}

const handleInput = debounce(() => console.log("Input event occurred"), 1000);

document.addEventListener("input", handleInput);

在上面的代码中,debounce 函数将返一个新函数,该函数使用 setTimeout 延迟执行处理程序。如果在 delay 时间内再次触发该事件,则 setTimeout 将被取消并重新启动。

节流是指在一段时间内只允许一个事件被触发。如果更多事件触发,则将被忽略,这是为了避免处理程序被多次调用的问题。

function throttle(func, delay) {
  let timeout;
  let lastRun = 0;

  return function() {
    const context = this;
    const args = arguments;

    if (Date.now() - lastRun >= delay) {
      func.apply(context, args);
      lastRun = Date.now();
    } else {
      clearTimeout(timeout);

      timeout = setTimeout(() => {
        func.apply(context, args);
        lastRun = Date.now();
      }, delay - (Date.now() - lastRun));
    }
  };
}

const handleScroll = throttle(() => console.log("Scroll event occurred"), 1000);

document.addEventListener("scroll", handleScroll);

在上面的代码中,throttle 函数将返一个新函数,该函数在 delay 时间内只允许一个事件被触发。如果更多事件被触发,则将被忽略。

19. 什么是 JavaScript 的事件循环?

事件循环是指在 JavaScript 中处理异步事件的方式,它是由浏览器提供的。

事件循环是单个线程的。它持续监听待处理的事件队列,并在队列中发现可用事件时处理它们。

console.log("Start");

setTimeout(() => console.log("Timeout"), 0);

Promise.resolve().then(() => console.log("Promise"));

console.log("End");

在上面的代码中,setTimeoutPromise 都是异步的。setTimeout 的延迟时间是0,这意味着它将在当前事件循环的末尾处理。Promise 的 resolve 函数显式调用,将它添加到当前事件循环的末尾。因此,控制台将输出以下内容:

Start
End
Promise
Timeout

20. 什么是 JavaScript 中的事件捕获?

事件捕获是指从根元素开始向下指定元素的过程,直到达到正在监听事件的元素。这允许在事件到达指定元素之前对其进行处理。

<div class="box">
  <button>Click me!</button>
</div>
const button = document.querySelector("button");
const box = document.querySelector(".box");

button.addEventListener(
  "click",
  () => console.log("Button clicked"),
  { capture: true }
);

box.addEventListener("click", () => console.log("Box clicked"));

// 输出顺序:
// Box clicked
// Button clicked

在上面的代码中,单击按钮时,首先处理的是 box 元素的单击事件,因为它将从根元素向下处理事件。即使按钮的事件被声明为在捕获阶段处理 ({ capture: true }),该事件仍在冒泡阶段处理。

21. 什么是 JavaScript 中的事件监听?

事件监听是指使用 addEventListener() 方法将处理程序添加到事件的元素中。该方法允许我们指定要监听的事件类型、处理程序函数和是否使用事件捕获。

<button>Click me!</button>
const button = document.querySelector("button");

button.addEventListener("click", () => console.log("Button clicked"));

在上面的代码中,单击按钮时将触发 click 事件,并将处理程序添加到事件的按钮元素中。

22. 什么是闭包?

闭包是指一个函数能够访问并操作其外部函数的变量。这是由于JavaScript的词法作用域和函数可以在其定义的作用域之外执行的特性所导致的。

function greet(name) {
  let message = `Hello, ${name}!`;

  function getMessage() {
    return message;
  }

  return getMessage;
}

const greeting = greet("Jenny");
console.log(greeting()); // 输出 Hello, Jenny!

在上面的代码中,函数 greet 返回了 getMessage 函数,它可以访问外部函数 greet 中的变量 message

23. 什么是 Web Workers?

Web Workers 是一种浏览器 API,它允许我们在后台线程中运行 JavaScript 代码。这可以提高应用程序的性能并避免阻塞UI线程。

可以使用 new Worker() 构造函数创建 Web Worker,并且可以使用 postMessage() 方法将消息发送到 Worker 中,并使用 onmessage 事件处理程序接收来自 Worker 的消息。

// 声明一个新的 Worker
const worker = new Worker("worker.js");

// 向 Worker 发送一条消息
worker.postMessage("Hello, worker!");

// 处理来自 Worker 的消息
worker.onmessage = event => console.log(event.data);

在上面的代码中,worker.js 是一个包含 Worker 代码的文件。 Worker 将在后台线程中运行,因此可以发送和接收消息而不会对UI阻塞。

24. JavaScript 中的值和引用有什么区别?

JavaScript 中的值是指所有基本类型(如字符串、数字、布尔值和空值),它们的值是直接存储在变量中的。

JavaScript 中的引用是指所有复杂数据类型(如对象、数组和函数),它们的值是存储在内存中的地址,而不是存储在变量中的值。因此,当引用一个对象或其他复杂

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:你有必要知道的25个JavaScript面试题 - Python技术站

(0)
上一篇 2023年5月28日
下一篇 2023年5月28日

相关文章

  • 详解element-ui 表单校验 Rules 配置 常用黑科技

    详解element-ui 表单校验 Rules 配置 常用黑科技 在Element-UI表单组件中,我们可以很方便地使用校验规则来验证用户输入的数据,以保证数据的合法性。下面我们将详细讲解如何在Element-UI表单组件中使用校验规则。 绑定校验规则 我们可以通过设置rules属性来绑定校验规则。例如下面的代码,绑定了一个名为name的校验规则: <…

    JavaScript 2023年6月10日
    00
  • input 日期选择功能的javascript代码

    下面就为你详细讲解“input日期选择功能的javascript代码”的完整攻略。 为 input 元素添加日期选择 使用 input 元素时,我们经常需要选择日期。在 HTML5 中,我们可以使用 input 元素的 type 属性设置为 date 来显示日期选择控件。例如: <input type="date" id=&quot…

    JavaScript 2023年5月27日
    00
  • 腾讯QQ微博API接口获取微博内容

    接下来我将详细讲解“腾讯QQ微博API接口获取微博内容”的完整攻略,包含以下几个步骤: 注册腾讯开放平台,创建应用,拥有API Key和API Secret; 调用OAuth2.0授权接口,获取Access Token; 调用API接口,获取微博内容。 下面我将会逐一介绍每一步骤。 1. 注册腾讯开放平台,创建应用,拥有API Key和API Secret …

    JavaScript 2023年6月10日
    00
  • JS实现字符串转日期并比较大小实例分析

    当我们需要比较两个日期的大小时,通常需要将字符串类型的日期转换为JavaScript中的Date对象,然后使用比较运算符进行比较。下面是JS实现字符串转日期并比较大小的完整攻略。 1. 将字符串类型的日期转换为Date对象 可以使用Date对象的构造函数并传入字符串类型的日期来创建一个Date对象。 var dateString = "2022-0…

    JavaScript 2023年5月27日
    00
  • JavaScript 接口原理与用法实例详解

    JavaScript 接口原理与用法实例详解 什么是 JavaScript 接口 JavaScript 接口是指一组被暴露出来供其他代码使用的方法和属性。接口允许开发者遵循“面向接口编程”的思想,而不是直接接触和修改代码实现。 在使用接口时,只需知道其提供的方法和属性,就可以进行调用,而不需要详细了解其实现原理。因此,在设计和实现程序时,使用接口可以实现代码…

    JavaScript 2023年5月27日
    00
  • JavaScript中数组去除重复的三种方法

    以下是“JavaScript中数组去除重复的三种方法”的完整攻略。 方法一:使用双重循环 算法思路 使用一个外层循环遍历数组元素,然后在外层循环内部再嵌套一个内层循环遍历前面的元素,依次与当前元素比较,如果有相同的就将其删除。 代码示例 function unique1(arr) { for (var i = 0; i < arr.length; i+…

    JavaScript 2023年5月27日
    00
  • 原生JS实现简单的倒计时功能示例

    下面我将详细讲解如何使用原生JS实现简单的倒计时功能。 编写HTML结构 首先,我们需要在HTML页面中创建一个倒计时的容器,可以使用<div>元素,并为其设置id属性,便于在JavaScript中操作。 <div id="countdown"></div> 编写JavaScript代码 接下来,我们使…

    JavaScript 2023年5月27日
    00
  • 详解Nginx服务器中的Socket切分

    详解Nginx服务器中的Socket切分 本文将详细介绍Nginx服务器中的Socket切分机制,包括其作用、实现原理、应用场景和示例说明,以帮助读者更好地理解和应用。 作用 Nginx服务器中的Socket切分是一项优化技术,旨在提高服务器性能和稳定性。具体来说,它可以将一个完整的Socket连接切分成多个子连接,将流量分散到多个进程或线程中处理,从而减轻…

    JavaScript 2023年5月28日
    00
合作推广
合作推广
分享本页
返回顶部