前端高频面试题及答案汇总

13次阅读

共计 1533 个字符,预计需要花费 4 分钟才能阅读完成。

浏览器

关于微任务和宏任务在浏览器的执行顺序是这样的:

执行一个 task(宏任务)
执行完 micro-task 队列(微任务)
如此循环往复下去

Node

Node 的事件循环是 libuv 实现的,引用一张官网的图:

大体的 task(宏任务)执行顺序是这样的:

timers 定时器:本阶段执行已经安排的 setTimeout() 和 setInterval() 的回调函数。
pending callbacks 待定回调:执行延迟到下一个循环迭代的 I/O 回调。
idle, prepare:仅系统内部使用。
poll 轮询:检索新的 I/O 事件; 执行与 I/O 相关的回调(几乎所有情况下,除了关闭的回调函数,它们由计时器和 setImmediate() 排定的之外),其余情况 node 将在此处阻塞。
check 检测:setImmediate() 回调函数在这里执行。
close callbacks 关闭的回调函数:一些准备关闭的回调函数,如:socket.on(‘close’, …)。
微任务和宏任务在 Node 的执行顺序

Node 10 以前:

执行完一个阶段的所有任务
执行完 nextTick 队列里面的内容
然后执行完微任务队列的内容
Node 11 以后:
和浏览器的行为统一了,都是每执行一个宏任务就执行完微任务队列。

未完待续,点击查看更多细节:https://github.com/Advanced-F…

介绍模块化发展历程
可从 IIFE、AMD、CMD、CommonJS、UMD、webpack(require.ensure)、ES Module、<script type=”module”> 这几个角度考虑。

解答:

模块化主要是用来抽离公共代码,隔离作用域,避免变量冲突等。

IIFE:使用自执行函数来编写模块化,特点:在一个单独的函数作用域中执行代码,避免变量冲突。


AMD:使用 requireJS 来编写模块化,特点:依赖必须提前声明好。

CMD:

使用 seaJS 来编写模块化,特点:支持动态引入依赖文件。

CommonJS:nodejs 中自带的模块化。

var fs = require('fs');
UMD:兼容 AMD,CommonJS 模块化语法。

webpack(require.ensure):webpack 2.x 版本中的代码分割。

ES Modules:ES6 引入的模块化,支持 import 来引入另一个 js。

import a from ‘a’;

全局作用域中,用 const 和 let 声明的变量不在 window 上,那到底在哪里?如何去获取?。
在 ES5 中,顶层对象的属性和全局变量是等价的,var 命令和 function 命令声明的全局变量,自然也是顶层对象。

var a = 12;
function f(){};

console.log(window.a); // 12
console.log(window.f); // f(){}

但 ES6 规定,var 命令和 function 命令声明的全局变量,依旧是顶层对象的属性,但 let 命令、const 命令、class 命令声明的全局变量,不属于顶层对象的属性。let aa = 1;
const bb = 2;

console.log(window.aa); // undefined
console.log(window.bb); // undefined

在哪里?怎么获取?通过在设置断点,看看浏览器是怎么处理的:


通过上图也可以看到,在全局作用域中,用 let 和 const 声明的全局变量并没有在全局对象中,只是一个块级作用域(Script)中

怎么获取?在定义变量的块级作用域中就能获取啊,既然不属于顶层对象,那就不加 window(global)呗。

let aa = 1;
const bb = 2;

console.log(aa); // 1
console.log(bb); // 2

介绍下 BFC 及其应用。

正文完
 0