整理一些面试遇到的问题,提供参考
1. 闭包原理和使用,js垃圾回收机制
for( var i = 0; i <3; i++){
(function(i){
setTimeout(function(){
console.log(i)
}, 1000*i)
})(i)
}
// 0,1,2秒之后打印 0,1,2
function fn(){
var a = 3
return function(){
console.log(a++)
}
}
fn()() // 3
fn()() // 3
var fn_n = fn()
fn_n() // 3
fn_n() // 4
每次外部函数执行的时 候,外部函数的引用地址不同,都会重新创建一个新的地址,key = value,key 被删除了 value 常驻内存中,所以fn_n找到了fn函数中变量的最终值。
关于垃圾回收机制先讲两种,标记清除、引用计数、标记压缩。
标记清除
- GC roots 根集,一组必须活跃的引用
- Tracing GC 回收器扫描是从GC roots触出发,有引用关系能被遍历到的对象称为可达对象,判定存活其余则判定死亡
从根集出发,将根集引用的对象Obj放入Unscanned未扫描集中并通过对象header属性写入reached可达标志标识为1,Obj从Unscanned中释放,将Obj引用的对象再放入Unscanned,最后所有可达对象标识为1,进入清扫阶段,
reached为0的对象放入Free释放集合等待回收。回收之后存活的对象 reached 标志位归还位0,进行下一轮。
引用计数
对象新增了一个引用,引用计数+1,引用释放时引用计数-1,无法解决循环引用的问题。
标记压缩
与标记清除法类似,清除阶段会将上一轮存活对象压缩到内存的一端,之后清理边界,可以减少内存碎片,避免分配大对象时空间不够。