WeakMap 的引用是弱引用,gc 的时候会忽略这种引用。即如果一个对象只有这种弱引用的时候,
会直接被垃圾回收掉。
我们用代码看下和 Map 的差别,
let obj = {name: 'fedaily'}
const map = new Map()
map.set('account', obj)
map.get('account') // {name: 'fedaily'}
obj = null // 这里将 obj 置为 null
map.get('account') // 这里其实 obj 值还在 {name: 'fedaily'}
从 Map 这个例子可以看出来,obj 被 map 一直引用着,那么垃圾回收器处理时认为 {name: ‘fedaily’} 还有其他引用,就不会回收它。如果需要彻底删除它,需要 map.delete(‘account’)。
我们再来看下 WeakMap:
let obj = {name: 'fedaily'}
const weakmap = new WeakMap()
weakmap.set(obj, 'account') // WeakMap 的 key 必须是对象,具体用法这里不展开,可以看 MDN 上的介绍
weakmap.get(obj) // {name: 'fedaily'}
obj = null // 这里将 obj 置为 null
weakmap.get('account') // undefined 这里就没有了
这里当我们将 obj 置为 null 的时候,obj 整个就被垃圾回收了。包括 weakmap 里面保存的值。
通过这两个对比,我们很容易理解 WeakMap 描述的对键对象的引用是弱引用的含义。
WeakMap 还有一个特性就是无法遍历所有的 key。是这种弱引用特性导致的。
还是以上面那个例子说明,当 obj=null 的时候,如果垃圾回收器没有执行,那么这个时候 weakmap.get(obj)其实是有值的,但如果垃圾回收器执行过了,你再访问 weakmap.get(obj)就是返回 undefined 了。
所以这就导致了 WeakMap 无法遍历所有 key 的问题。
希望这些可以帮你理解掌握该在什么时候用 WeakMap,什么时候用 Map。
公众号: 前端收藏家。只收藏好的,只推荐好的