我想起上回找工作有一个面试,对面面试官问我
- “你讲讲js中,new关键字做了什么?”
我一下就蒙了,我背了这么多面试题,难道最终要栽在这个倒霉题目上吗!我一点准备也没有,只能磕磕巴巴说出自己的一些想法: - “new的时候开辟了一个新的空间和地址,再在这个空间里创建一个对象,让它指向这个地址。”
- “说得挺好的,继续往下说。”
- “……”
我就知道这场面试凉凉了,回来以后我马上问了一个资历更深的朋友,他的回答和我差不多,我立马打开百度查阅了资料,原来我只回答了20%,那么
new
,到底是做了什么操作!
一、new 运算符的实现机制
new( ) 到底做了什么?
- 创建一个新的
空对象
- 设置原型,将对象的原型设置为函数的
prototype
对象 - 让函数的
this
指向这个对象,执行构造函数的代码(为这个新对象添加属性) - 判断函数的返回值类型,如果是值类型,返回创建的对象,如果是引用类型,就返回这个引用类型的对象
原来
new
做了这么多事情 😮
二、EventLoop 事件循环
这也是面试题中最爱考的内容,说它难也不难,说它容易又很容易犯错 😥
2.1 浏览器中的事件环(Event Loop)
JavaScript
是单线程的,为了防止一个函数执行时间过长而阻塞后面的代码,所以会将同步代码放入主线程中依次执行,异步代码不进入主线程,而进入异步队列。异步队列又分为宏任务队列和微任务队列,因为宏任务队列的执行时间较长,所以微任务队列要优先于宏任务队列。
微任务
语言本身提供的,比如 promise.then
队列的代表有:Promise.then
、MutationObserver
宏任务
诉诸环境提供的,比如浏览器:
队列的代表有:ajax
、setImmediate
、setTimeout
、setInterval
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