WeakSet 和 WeakMap都是为了解决内存泄漏的问题
WeakSet
相同点: 不重复值的集合
不同点:
- WeakSet 的成员只能是对象,不能是其他类型的值, WeakSet 里面的引用,都不计入垃圾回收机制, WeakSet 适合临时存放一组对象,以及存放跟对象绑定的信息
- 不可遍历
- 有三个方法:
add, has, delete - 没有size属性,没办法遍历他的成员
- WeakSet 的一个作用是存储DOM节点,不用担心这些节点从文档移除时候,会引发内存泄漏
ws.size // undefined
ws.forEach // undefined
ws.forEach(function(item){ console.log('WeakSet has ' + item)})
// TypeError: undefined is not a function
const foos = new WeakSet()
class Foo {
constructor() {
foos.add(this)
}
method () {
if (!foos.has(this)) {
throw new TypeError('Foo.prototype.method 只能在Foo的实例上调用!');
}
}
}
WeakMap
- WeakMap 跟Map相似,也是生成键值对的集合
- 区别1: 只接收对象作为键名,null除外
- 区别2:
WeakMap的键名所指向的对象,不计入垃圾回收机制 - 如果你要往对象上添加数据,又不想干扰垃圾回收机制,就可以使用 WeakMap
WeakMap的专用场合就是,它的键所对应的对象,可能会在将来消失- 没有遍历操作,也就是
keys() ,values(), entries()也没有size - 只有四个方法,get set has delete
// WeakMap 可以使用 set 方法添加成员
const wm1 = new WeakMap();
const key = {foo: 1};
wm1.set(key, 2);
wm1.get(key) // 2
// WeakMap 也可以接受一个数组,
// 作为构造函数的参数
const k1 = [1, 2, 3];
const k2 = [4, 5, 6];
const wm2 = new WeakMap([[k1, 'foo'], [k2, 'bar']]);
wm2.get(k2) // "bar"
const map = new WeakMap();
map.set(1, 2)
// TypeError: 1 is not an object!
map.set(Symbol(), 2)
// TypeError: Invalid value used as weak map key
map.set(null, 2)
// TypeError: Invalid value used as weak map key
经典
const wm = new WeakMap();
const element = document.getElementById('example');
wm.set(element, 'some information');
wm.get(element) // "some information"
用途
let myWeakmap = new WeakMap();
myWeakmap.set(
document.getElementById('logo'),
{timesClicked: 0})
;
document.getElementById('logo').addEventListener('click', function() {
let logoData = myWeakmap.get(document.getElementById('logo'));
logoData.timesClicked++;
}, false);