JS垃圾回收
一、什么是垃圾
1、没有被引用的,一般都是垃圾;但是有个特例,比如有三个对象互相引用,形成了一个环,但它们还是垃圾;
2、所有的全局变量都不是垃圾,因为你随时有可能会用到它;
3、局部变量有生命周期,当退出这个函数后,这个局部变量就成了垃圾;它会在每次函数执行的时候再重新声明;
二、浏览器是怎么找到这些垃圾并清除它们的?
具体方法可参考:这里
1、标记清除法
简单来说,就是从全局变量开始,一层一层往下标记,把所有引用到的对象都标记起来,没有标记的清除掉;
2、引用计数法
记录每个对象被引用的次数,每次新建对象,赋值引用的时候加1,删除引用减1,一旦为0就直接回收掉;
Eventloop
一、首先,要说一下JavaScript的单线程
- JS引擎是单线程的,也就是说同一时间只能一件事,为了提高线程的利用率,就分成了同步任务和异步任务;
- 同步任务是在主线程上排队执行的任务,只有前一个任务执行完了,才去执行下一个任务;
- 异步任务就是不进入主线程、而是进入任务队列的任务;
- 异步任务有了运行结果就会在任务队列放置一个事件,当当前所有的同步任务都执行完毕后,系统就会去读取任务队列里的事件,那些对应的异步任务就会结束等待状态,进入主线程,开始执行;
二、宏任务(Macrotask)和微任务(Microtask)
- 宏任务和微任务表示异步任务的两种分类;
- 宏任务一般包括整体代码script、setTimeout、setInterval、O/I、UI渲染;
- 微任务一般包括Promise、process.nextTick、Object.observe;
- 先执行宏任务再执行微任务,就是先执行宏任务,再去清空第一次宏任务中生出的微任务,如果第一次宏任务中又产生了宏任务,那么再继续执行这个宏任务,直到没有任务为止;
- nextTick先于所有的回调执行,永远先于setTimeout、setInterval(setTimeout的最小间隔是4ms,即使写了0,也是4ms后执行);
- new Promise(fn).then(success) 期中 fn 是立即执行的,success 会被放入 Mi 任务;
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0);
let promise = new Promise((resolve, reject)=>{
console.log(1)
resolve()
})
promise.then(function() {
console.log('promise1');
}).then(function() {
console.log('promise2');
});
执行结果:
script start
1
promise1
promise2
setTimeout

网友评论