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

yizhihongxing

下面是详细讲解“你有必要知道的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日

相关文章

  • js 图片缩放特效代码

    下面是详细讲解“js 图片缩放特效代码”的完整攻略: 什么是图片缩放特效 图片缩放特效指的是使用 JavaScript 对图片进行放大、缩小、旋转、移动等视觉特效处理,以增强用户对页面的交互感和体验。常见的应用场景有图片轮播、幻灯片展示、相册浏览等。 如何实现图片缩放特效 实现图片缩放特效需要使用 JavaScript 和 CSS,具体实现过程如下: 定义 …

    JavaScript 2023年6月11日
    00
  • Swift的函数式编程详解

    Swift的函数式编程详解 什么是函数式编程 函数式编程(Functional Programming)是一种编程范式,在函数式编程中,函数是一等公民,函数可以作为参数传递给另一个函数,也可以作为返回值返回。函数式编程强调构建无副作用的函数,可变状态(Mutable State)被限制或者禁止,这样可以避免程序因为状态引发的各种问题。 Swift中通过高阶函…

    JavaScript 2023年5月28日
    00
  • 基于 D3.js 绘制动态进度条的实例详解

    这里我将为大家详细讲解“基于 D3.js 绘制动态进度条的实例详解”的完整攻略。 1. D3.js 简介 在开始讲解如何绘制动态进度条之前,先简单介绍一下 D3.js。D3.js 是一个用于操作文档的 JavaScript 库。D3.js 可以帮助开发者使用 HTML、SVG、CSS 和 JavaScript 创建动态交互数据图表和数据可视化效果。 2. 进…

    JavaScript 2023年6月10日
    00
  • Chrome扩展页面动态绑定JS事件提示错误

    Chrome扩展开发中,我们经常需要在选项页面或者弹窗页面中动态绑定JS事件。但是在实际开发的过程中,发现有时候动态绑定事件会出现错误,需要我们进行排查。下面是一个完整攻略,帮助开发人员解决这个问题。 1. 确认目标事件是否正确绑定 在进行动态绑定事件时,我们需要确认目标事件是否正确绑定。例如,我们在页面中找到一个按钮,需要在按钮上动态绑定click事件,如…

    JavaScript 2023年6月10日
    00
  • document.getElementById的简写方式(获取id对象的简略写法)

    获取id对象是JavaScript常见的操作之一,而document.getElementById是获取id对象的常用方式。但是,在书写代码的过程中,为了方便,我们常常使用id对象的简略写法。 1. 通用的文档对象模型(DOM): 通常情况下,获取文档对象模型中的元素需要使用document.getElementById方法。该方法接受一个字符串参数,代表要…

    JavaScript 2023年6月10日
    00
  • JQuery实现隐藏和显示动画效果

    JQuery是一种JavaScript库,它为HTML文档操作和动画效果提供了简单易用的API。本文将讲解如何使用JQuery实现隐藏和显示动画效果。 1. 引入JQuery库 在使用JQuery之前,我们需要将其引入到HTML文档中。可以从JQuery官网https://jquery.com/下载最新的JQuery版本,并将其引入到HTML文档中。 &lt…

    JavaScript 2023年6月10日
    00
  • 详解javascript的变量与标识符

    我们来详细讲解JavaScript的变量与标识符。 变量 在JavaScript中,变量是用于存储数据的容器,它们可以被任何地方引用或更改。在使用变量之前,需要先声明它们,以告诉JavaScript编译器它们的类型。 声明变量有三种方式: 使用var关键字 var name = ‘张三’; 使用let关键字(ES6新增) let age = 20; 使用co…

    JavaScript 2023年5月18日
    00
  • ES6中module模块化开发实例浅析

    ES6中module模块化开发实例浅析 在ES6之前,JavaScript并没有原生的模块化机制,开发者们采用了各种方式实现模块化,比如立即执行函数、命名空间等。但这些方式都存在缺点,比如代码可读性差、变量污染等问题。ES6中提供了原生的模块化机制,使得我们可以更加方便、清晰地组织和管理代码。 使用ES6 module规范 ES6中的module规范使用im…

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