LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

JavaScript 开发中的常见面试问题

admin
2024年11月29日 9:31 本文热度 452

在本文中,我们将探讨许多开发人员难以解决的 JavaScript 面试问题,但这些是 JavaScript 的基本原理。掌握它们不仅可以提高您的面试成绩,还可以提高您创建和调试 JavaScript 代码的能力。

JavaScript 是单线程语言还是多线程语言?

JavaScript 是一种单线程语言,这意味着它使用单个调用堆栈来执行代码。它按顺序一次处理一个任务,每个任务都需要在下一个任务开始之前完成。因此,JavaScript 无法一次运行多个任务。

console.log("Start");

setTimeout(() => {
  console.log("Task 1 complete");
}, 2000); // Simulate a task that takes 2 seconds

console.log("Middle");

setTimeout(() => {
  console.log("Task 2 complete");
}, 1000); // Simulate a task that takes 1 second

console.log("End");

你能预测输出吗?我看看。在上面的代码中,首先记录消息 Start、Middle 和 End,因为它们是同步代码。之后,打印 Task 2 complete,然后打印 Task 1 complete这是因为 setTimeout 是异步的,它的回调只有在同步代码完成运行后才会执行。

如何在 JavaScript 中实现异步操作

JavaScript 使用 Promise 处理异步操作。Promise 是一个对象,它表示异步操作的最终完成(或失败)。当 Promise 解析或拒绝时,它的回调被放置在微任务队列中。

事件循环通过在空闲时将回调推送到调用堆栈上来处理这些回调,从而确保异步操作得到有效管理并且不会阻塞主线程。


console.log("Start");

// Creating a Promise that resolves after 1 second
const promise = new Promise((resolve) => {
  setTimeout(() => {
    resolve("Promise Resolved");
  }, 1000);
});

// Adding a callback to be executed when the Promise resolves
promise.then((message) => {
  console.log(message);
});

console.log("End");

你能预测输出吗?我看看。在上面的代码中,首先记录 Start 和 End,因为它们是同步代码。1 秒后,Promise 解析并记录 Promise Resolved。发生这种情况是因为事件循环仅在同步代码完成后才处理微任务队列。

为什么你应该避免阻塞 JavaScript 中的主线程

JavaScript 是一种单线程语言,这意味着如果主线程被阻塞,则在当前任务完成之前,其他代码都无法运行。这可能会导致显着的减速,甚至导致应用程序崩溃。为了保持流畅的性能并确保应用程序保持响应,最佳做法是避免阻塞主线程。你可以使用 Promise 和 async/await 来有效地处理异步任务。


console.log("Start");

// Blocking the main thread with a long-running operation
function blockMainThread({
  const start = Date.now();
  while (Date.now() - start < 3000) {
    // Busy-wait for 3 seconds
  }
  console.log("Blocking Operation Complete");
}

blockMainThread();

console.log("End");

你能预测输出吗?让我们来分析一下。在上面的代码中,首先打印 Start。然后调用 blockMainThread() 函数。在此函数中,一个名为 start 的变量被初始化为当前时间。while 循环一直运行到 3 秒过去 (Date.now() - start < 3000)。此循环会阻止主线程,因为它会一直运行,从而阻止执行任何其他代码。循环完成后,将记录 Blocking Operation Complete,然后记录 End

JavaScript 如何执行代码

JavaScript 是一种单线程语言,这意味着它按顺序执行代码,一次执行一个任务。当 JavaScript 代码运行时,它会创建一个全局执行上下文并将其推送到调用堆栈上。此全局执行上下文包含所有全局变量、函数和引用,例如 this 和 window 对象。

每当调用函数时,JavaScript 都会为该函数创建一个新的执行上下文,并将其推送到调用堆栈上。然后 JavaScript 执行函数内的代码。函数完成运行后,其执行上下文将从调用堆栈中弹出,将控制权返回给前一个上下文。


const language = "JavaScript";

function print({
  console.log("Follow @amitrai_dev for more such articles!");
}

console.log(language);

print();

执行上述代码时,JavaScript 会创建一个全局执行上下文,其中包括全局变量 language 和函数 print() 这个函数执行从打印 language 变量的值开始,即 JavaScript,接下来调用 print() 函数,为其创建一个新的执行上下文。在 print() 函数中,消息 Follow @amitrai_dev for more such articles! 被打印到控制台。print() 函数完成后,其执行上下文将从调用堆栈中删除。最后,全局执行上下文结束,标志着程序的结束。

什么是 JavaScript 中的事件循环

JavaScript 中的事件循环是一种监控调用堆栈和任务队列的机制。当调用堆栈为空时,事件循环从任务队列中获取回调函数,并将它们推送到调用堆栈上执行。任务队列有两种类型:任务队列(或宏任务队列)和微任务队列(或优先级队列)。微任务队列具有更高的优先级,并在任务队列之前处理。事件循环通过管理异步操作来创造多线程的错觉,即使 JavaScript 本身是单线程的。

console.log("Start");

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

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

console.log("End");

你能预测输出吗?让我们来分析一下。在上面的代码中,首先记录 Start 和 End,因为它们是同步操作。现在接下来打印什么?您能猜到它是 setTimeout 代码还是 Promise 代码吗?提示如下:微任务在宏任务之前执行。

Promise 回调的优先级更高,因为它被推送到 Microtask Queue(优先级队列),而 setTimeout 回调被推送到 Task Queue(宏任务队列)。因此,事件循环在 Task Queue 之前处理 Microtask Queue。因此,将首先打印 Promise Resolved。一旦微任务队列为空,事件循环就会处理任务队列,打印 Timeout。

结论

这就是这篇文章的全部内容。我希望你觉得它有用。在面试前准备这些问题对于确保您的 JavaScript 基础知识扎实非常有帮助,这将帮助您在面试中脱颖而出。

本文首发于公众号“web前端开发之旅”,转载请注明出处!


该文章在 2024/11/29 9:31:01 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved