Js的事件循环
js是单线程的,所以它有一个执行栈,遵循后进先出原则,先将函数的上下文环境压入栈中,最后将优先级较高的函数推入栈,运行时将最后推入栈中的函数取出来,当遇到微任务时,会将微任务的回调放到微任务列表中,同样当遇到定时器如宏任务时,会将宏任务的回调放到宏任务队列中,当执行栈运行完后,再查看微任务队列,依次执行微任务,当微任务执行完后,再调取一个宏任务,在当前宏任务执行完后,在查看微任务,依此循环。。。。。。
补充知识
在“微任务清空”之后,“下一个宏任务”开始之前,浏览器会有一个**渲染(Render)**的机会。
循环公式
执行栈 -> 所有微任务 -> UI 渲染 (如果有) -> 一个宏任务 -> 所有微任务
经典例题
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2');
}
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0);
async1();
new Promise(function(resolve) {
console.log('promise1');
resolve();
}).then(function() {
console.log('promise2');
});
console.log('script end');
原型与原型链
Js的所有对象都有自己的原型prototype, 除了null和undefined, 原型也有自己的原型,这样依次向上宿根,形成了原型链。
console.log(Object.getPrototypeOf(p1) === Person.prototype); // true
console.log(Object.getPrototypeOf(Person) === Function.prototype); // true
console.log(Object.getPrototypeOf(Function) === Function.prototype); // true
console.log(Object.getPrototypeOf(Function.prototype) === Object.prototype); // true
console.log(Object.getPrototypeOf(Object.prototype) === null); // true
console.log(Object.getPrototypeOf(Object) === Function.prototype); // true