跳到主内容

Javascript基础面试题(二)

本文整理了 Javascript 基础面试题,包括箭头函数与普通函数的区别, Javascript 的事件循环,Service Worker 是什么

箭头函数与普通函数的区别

  1. 箭头函数的 this 对象,是定义时所在的对象,而普通函数的 this 对象,是调用时所在的对象。

  2. 箭头函数内部没有 arguments 变量,而普通函数可以使用 arguments 变量获取参数。

  3. 箭头函数无法使用 new 关键字来实例化,是因为它没有原型(prototype)。

new 的实现原理

Javascript 的事件循环

Js 引擎在执行代码时候会产生执行栈,当调用异步 API,例如 setTimeoutsetIntervalPromise 等回调触发时,就会进入异步任务队列,当同步代码执行完成后,就会去异步队列取出回调函数并执行,这样就形成了一个事件循环。在 Javascript 中有两种任务类型,分别是 宏任务 和 微任务

宏任务

script(主代码块)、setTimeoutsetIntervalsetImmediateI/OUI rendering

微任务

process.nextTick(Nodejs) 、PromiseObject.observeMutationObserver

NodeJs 的事件循环相对比较复杂,一个事件循环表示如下

   ┌───────────────────────┐
┌─>│ timers │<————— 执行 setTimeout()、setInterval() 的回调
│ └──────────┬────────────┘
| |<-- 执行所有 Next Tick Queue 以及 MicroTask Queue 的回调
│ ┌──────────┴────────────┐
│ │ pending callbacks │<————— 执行由上一个 Tick 延迟下来的 I/O 回调(待完善,可忽略)
│ └──────────┬────────────┘
| |<-- 执行所有 Next Tick Queue 以及 MicroTask Queue 的回调
│ ┌──────────┴────────────┐
│ │ idle, prepare │<————— 内部调用(可忽略)
│ └──────────┬────────────┘
| |<-- 执行所有 Next Tick Queue 以及 MicroTask Queue 的回调
| | ┌───────────────┐
│ ┌──────────┴────────────┐ │ incoming:
│ │ poll │<─────┤ connections,- (执行几乎所有的回调,除了 close callbacks、timers、setImmediate)
│ └──────────┬────────────┘ │ data, etc.
| | |
| | └───────────────┘
| |<-- 执行所有 Next Tick Queue 以及 MicroTask Queue 的回调
| ┌──────────┴────────────┐
│ │ check │<————— setImmediate() 的回调将会在这个阶段执行
│ └──────────┬────────────┘
| |<-- 执行所有 Next Tick Queue 以及 MicroTask Queue 的回调
│ ┌──────────┴────────────┐
└──┤ close callbacks │<————— socket.on('close', ...)
└───────────────────────┘

说出下面代码执行的结果

console.log("script start");

async function async1() {
await async2();
console.log("async1 end");
}
async function async2() {
console.log("async2 end");
}
async1();

setTimeout(function () {
console.log("setTimeout");
}, 0);

new Promise((resolve) => {
console.log("Promise");
resolve();
})
.then(function () {
console.log("promise1");
})
.then(function () {
console.log("promise2");
});

console.log("script end");

结果是 script start -> async2 end -> Promise -> script end -> async1 end -> promise1 -> promise2 -> setTimeout

Service Worker 是什么

Service workers  本质上充当 Web 应用程序、浏览器与网络(可用时)之间的代理服务器。这个 API 旨在创建有效的离线体验,它会拦截网络请求并根据网络是否可用来采取适当的动作、更新来自服务器的的资源。它还提供入口以推送通知和访问后台同步 API