前端语法&规范(三)

94 阅读3分钟

我想起上回找工作有一个面试,对面面试官问我

  • “你讲讲js中,new关键字做了什么?”
    我一下就蒙了,我背了这么多面试题,难道最终要栽在这个倒霉题目上吗!我一点准备也没有,只能磕磕巴巴说出自己的一些想法:
  • “new的时候开辟了一个新的空间和地址,再在这个空间里创建一个对象,让它指向这个地址。”
  • “说得挺好的,继续往下说。”
  • “……” 我就知道这场面试凉凉了,回来以后我马上问了一个资历更深的朋友,他的回答和我差不多,我立马打开百度查阅了资料,原来我只回答了20%,那么new,到底是做了什么操作!

一、new 运算符的实现机制

new( ) 到底做了什么?
  1. 创建一个新的空对象
  2. 设置原型,将对象的原型设置为函数的prototype对象
  3. 让函数的this指向这个对象,执行构造函数的代码(为这个新对象添加属性)
  4. 判断函数的返回值类型,如果是值类型,返回创建的对象,如果是引用类型,就返回这个引用类型的对象 原来new做了这么多事情 😮

二、EventLoop 事件循环

这也是面试题中最爱考的内容,说它难也不难,说它容易又很容易犯错 😥

2.1 浏览器中的事件环(Event Loop)

JavaScript 是单线程的,为了防止一个函数执行时间过长而阻塞后面的代码,所以会将同步代码放入主线程中依次执行,异步代码不进入主线程,而进入异步队列。异步队列又分为宏任务队列和微任务队列,因为宏任务队列的执行时间较长,所以微任务队列要优先于宏任务队列。

  • 微任务 语言本身提供的,比如 promise.then
    队列的代表有:Promise.thenMutationObserver
  • 宏任务 诉诸环境提供的,比如浏览器:
    队列的代表有:ajaxsetImmediatesetTimeoutsetInterval
2.2 Node 环境中的事件环(Event Loop)

Node是基于V8引擎的运行在服务端的JavaScript运行环境。在处理高并发、I/O密集(文件操作、网络操作、数据库操作等)场景有明显的优势。

Node的Event Loop与浏览器的不太一样。

三、setTimeout、Promise、async/await的区别

3.1 setTimeout

setTimeout的回调函数会被放到宏任务队列中,等到执行栈清空以后执行

3.2 Promise

Promise本身是同步的立即执行函数,当在executor中执行resolve或者reject的时候,此时是异步操作,会先执行then/catch等,当主栈完成后,才会去调用resolve/reject中存放的方法执行。

3.3 async / await

async函数返回一个promise对象,当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再执行函数体内后面的语句。

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

console.log('script start');
async1();
console.log('script end')

// 输出顺序:
// script start->async1 start->async2->script end->async1 end