如何通过JavaScript面试:高级水平

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

如何通过JavaScript面试:高级水平热门问题

\n\n

高级JavaScript开发人员或Node.js工程师职位的面试,不仅仅是检查语法。面试官希望看到你对语言的深刻理解:事件循环是如何工作的,this上下文到底是什么,以及如何避免处理异步时的“回调地狱”。在本文中,我们将分析在高级水平面试中最常见和最棘手的问题。准备好不仅仅是阅读答案,而是要理解其机制。

\n\n

1. 事件循环、调用栈和微任务(微任务 vs 宏任务)

\n\n

这可能是Node.js面试中最常见的一个模块。问题通常是:“这段代码会输出什么,顺序是什么?”

\n\n
console.log('1');\n\nsetTimeout(() => console.log('2'), 0);\n\nPromise.resolve().then(() => console.log('3'));\n\nprocess.nextTick(() => console.log('4'));\n\nconsole.log('5');
\n\n

正确答案: 1, 5, 4, 3, 2。

\n\n

解析:

\n
    \n
  • 同步代码 (1, 5) 首先执行。
  • \n
  • process.nextTick() — 优先级最高的微任务。它在当前操作之后立即执行,但在任何其他微任务(Promise)和宏任务(setTimeout)之前。
  • \n
  • Promise.then() — 也是微任务,但其优先级低于 nextTick。
  • \n
  • setTimeout(cb, 0) — 宏任务。它仅在调用栈和所有微任务(所有 nextTick 和 Promise)完全清空后执行。
  • \n
\n\n

如何正确回答: 解释Node.js有事件循环阶段。微任务(process.nextTick 和 Promise)在阶段之间处理。宏任务(setTimeout、setInterval、I/O)在阶段内部处理。nextTick 是一个非标准但非常重要的队列,如果递归使用它,可能会阻塞事件循环。

\n\n

2. this 上下文及其“丢失”

\n\n

问题:“this 在JavaScript中是如何工作的?请举一个 this 丢失的例子,并说明如何修复。”

\n\n

高级水平意味着你需要知道4条规则:

\n
    \n
  1. new 绑定 — 当通过 new 调用函数时,this 指向新创建的对象。
  2. \n
  3. 显式绑定 — call、apply、bind。
  4. \n
  5. 隐式绑定 — 当函数作为对象的方法调用时(obj.method())。
  6. \n
  7. 默认绑定 — 全局对象(Node.js中的 global,浏览器中的 window)或严格模式下的 undefined。
  8. \n
\n\n

上下文丢失的例子:

\n
const user = {\n  name: 'Alice',\n  greet() {\n    console.log(`Hello, ${this.name}`);\n  }\n};\n\nconst greetFn = user.greet;\ngreetFn(); // Hello, undefined
\n\n

为什么? 我们将方法赋值给了一个变量。现在 greetFn() 在没有对象上下文(user)的情况下被调用。this 绑定到了全局对象(或严格模式下的 undefined)。

\n\n

如何修复:

\n
    \n
  • 使用 bind:const greetFn = user.greet.bind(user);
  • \n
  • 使用箭头函数(它没有自己的 this,而是从外部词法环境获取)。
  • \n
  • 通过 call/apply 调用:greetFn.call(user)。
  • \n
\n\n

附加问题: “如果 user.greet 被传递给 setTimeout 会发生什么?” — 同样的丢失效果。通过 bind 或在回调中使用箭头函数来修复。

\n\n

3. 闭包

博客

书籍推荐