JavaScript学习-WeakMap和Map的区别,WeakMap的原理,为什么能被GC??

一、GC(垃圾回收机制)?

  GC就是指垃圾回收机制,JavaScript里垃圾数据是不用手动清除,JS引擎中有个后台进程称为垃圾回收器,它监视所有的对象,观察对象是否可以被访问,然后按照固定的时间间隔周期性的删除掉那些不可访问的对象,常用的垃圾回收算法有:引用计数法和标记清除法。

引用计数法

  引用计数法就是给占用物理内存空间的对象附加一个计数器,当有其他的对象引用这个对象的时候计数器就加1,如果解除引用了就把计数器减1,当最后计数器为0的时候就会将该对象所占用的物理空间回收掉,此时就不可以反问这个对象了。

  引用计数很简单,但是它无法清除掉被循环引用的数据,如下:

function f() {
  var o1 = {};
  var o2 = {};
  o1.p = o2; // o1引用o2
  o2.p = o1; // o2引用o1
}

f();

  为了解决引用计数的问题,又引出了标记清除法。

标记清除法

  标记清除法分为两个阶段:

  • 标记阶段:标记阶段就是给活动的对象添加标记
  • 清除阶段:清除阶段就是清除掉没有标记(不活动)的对象。

  在开发的过程中,如果我们想让垃圾回收器回收一个对象,我们可以将这个对象的引用设置为null,这个时候就垃圾回收器就可以回收这个对象了,但是如果将一个对象设置为另外一个对象的属性或者值,这个时候在将前面那个对象设置为null,这样前面那个对象任然不可以被释放。

var a = {}; 
var arr = [a];

a = null; 
console.log(arr)
// [{}]

  如果作为 Map 的键喃?

var a = {}; 
var map = new Map();
map.set(a, '三分钟学前端')

a = null; 
console.log(map.keys()) // MapIterator {{}}
console.log(map.values()) // MapIterator {"三分钟学前端"}

  如果想让 a 置为 null 时,该对象被回收,该怎么做?

二、WeakMap和Map

  WeakMap和Map类似,都是一个存储对象的类型,但是也有一些不同:

  • Map的键可以是任何的类型,但是weakMap的键必须是对象类型;
  • Map是可以被迭代的,而weakMap是不可以被迭代的。
  • Map中键的引用是地址,如果两个地址不一样,就是不同的数据,而WeakMap对键的引用是“弱”引用,他所引用的键是可以被回收的。

  每个键对自己所引用对象的引用都是弱引用,在没有其他引用和该键引用同一对象,这个对象将会被垃圾回收(相应的key则变成无效的),所以,WeakMap 的 key 是不可枚举的。