WeakSet
WeakSet与Set
相同: 不重复的值的集合
不同
var ws = new WeakSet();
ws.add(1); // TypeError: Invalid value used in weak set
ws.add(Symbol()); // Uncaught TypeError: Invalid value used in weak set
- WeakSet中的对象都是弱引用,即垃圾回收机制不考虑WeakSet对该对象的引用
- 如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存。
- 无法引用WeakSet的成员,因此WeakSet是不可遍历的。
WeakSet使用与方法
创建
- WeakSet是一个构造函数,可以使用new命令,创建WeakSet数据结构。
var ws = new WeakSet();
- WeakSet可以接受一个数组或类似数组的对象作为参数。该数组的所有成员,都会自动成为WeakSet实例对象的成员(任何具有iterable接口的对象,都可以作为WeakSet的参数)。
var a = [[1,2], [3,4]];
var ws = new WeakSet(a);
- WeakSet的成员是数组成员,而不是数组本身。这意味着,数组的成员只能是对象。
var b = [3, 4];
var ws = new WeakSet(b); // Uncaught TypeError: Invalid value used in weak set
方法
- WeakSet.prototype.add(value): 向WeakSet实例添加一个新成员。
- WeakSet.prototype.delete(value): 清除WeakSet实例的指定成员。返回boolean表示是否成功。
- WeakSet.prototype.has(value): 返回一个布尔值,表示某个值是否存在于WeakSet实例中。
var ws = new WeakSet();
var obj = {};
var foo = {};
ws.add(window);
ws.add(obj);
console.log(ws.has(window)); // true
console.log(ws.has(foo)); // false
console.log(ws.delete(window)); // true
console.log(ws.has(window)); // false
特性
- WeakSet没有size属性,没有办法遍历它的成员.
- WeakSet不能遍历,是因为成员都是弱引用,随时可能消失,遍历机制无法保证成员的存在,很可能刚刚遍历结束,成员就取不到了
var ws = new WeakSet();
console.log(ws.size); // undefined
console.log(ws.forEach); // undefined
- WeakSet的一个用处,是储存DOM节点,而不用担心这些节点从文档移除时,会引发内存泄漏。
WeakMap
WeakMap与Map区别
var map = new WeakMap()
map.set(1, 2); // Uncaught TypeError: Invalid value used as weak map key
- 键名所指向的对象不计入垃圾回收机制(弱引用),其所对应的对象可能会被自动回收,当对象被回收后,WeakMap自动移除对应的键值对.
- 当对象被回收后,WeakMap自动移除对应的键值对。
WeakMap使用场合与目的
- WeakMap的专用场合就是,它的键所对应的对象,可能会在将来消失。
- WeakMap结构有助于防止内存泄漏
// 这demo怎么测试呀?好头疼
var wm = new WeakMap();
var element = document.getElementById('spchx');
wm.set(element, "Original");
wm.get(element); // "Original"
element.parentNode.removeChild(element);
var temp = element;
element = null;
wm.get(temp); // "Original"
// 使用Map
var wm = new Map();
var element = document.getElementsByTagName("div");
wm.set(element, "Original");
console.log(wm.get(element)); // "Original"
var temp = element;
element = null;
wm.get(temp); //
WeakMap特性与应用
基本特性
- 没有遍历操作(没有key()、values()、entries()方法,也没有size属性)
- 无法清空,即不支持clear方法.
- 这与WeakMap的键不被计入引用,被垃圾回收机制忽略有关。
- WeakMap只有四个方法:get()、set()、has()、delete()
典型应用
- WeakMap应用的典型场合就是DOM节点作为键名。
- WeakMap的另一个用处是部署私有属性。
let myElement = document.getElementById('logo-sub');
let myWeakmap = new WeakMap();
myWeakmap.set(myElement, {timesClicked: 0});
myElement.addEventListener('click', function() {
let logoData = myWeakmap.get(myElement);
logoData.timesClicked++;
myWeakmap.set(myElement, logoData);
}, false);