这是我参与8月更文挑战的第11天,活动详情查看:8月更文挑战
什么是WeakSet?
WeakSet
对象允许你将弱保持对象存储在一个集合中。只能存放引用类型(一个可迭代对象:包括 Array
,Map
,Set
,String
,TypedArray
,arguments
对象等等)作为参数,而Set参数都可以
WeakSet
结构与 Set 类似,也是不重复的值的集合,WeakSet
持弱引用:集合中对象的引用为弱引用,WeakSet
是不可枚举的。
为什么要用WeakSet?
WeakSet 的一个用处,是储存 DOM 节点,而不用担心这些节点从文档移除时,会引发内存泄漏。
下面是 WeakSet 的另一个例子。
const requests = new WeakSet();
class ApiRequest {
constructor() {
requests.add(this);
}
makeRequest() {
if(!request.has(this)) throw new Error("Invalid access");
// do work
}
}
比如上述代码,ApiRequest 类中想验证 this 对象的来源,于是需要一个集合来存所有通过构造函数构建的对象,ApiRequest 类却并不像参与到实例对象的生命周期中去,直接用 Set 的话,由于Set 对于实例对象存在引用,就会发生内存泄漏。
如果用 Set 改写。
const requests = new Set();
class ApiRequest {
constructor() {
requests.add(this);
}
makeRequest() {
if(!request.has(this)) throw new Error("Invalid access");
// do work
}
destory(){
requests.delete(this)
}
}
那么 ApiRequest 既不得不参与到生命周期的管理中去,另一方面作为消费者的一方还得时时刻刻记着需要 destory 。
使用
WeakSet 结构有以下三个方法。
- add(value) :向 WeakSet 实例添加一个新成员。
- delete(value) :清除 WeakSet 实例的指定成员。
- has(value) :返回一个布尔值,表示某个值是否在 WeakSet 实例之中。
var ws = new WeakSet();
var foo = {};
var bar = {};
ws.add(foo);
ws.add(bar);
ws.has(foo); // true
ws.has(bar); // true
ws.delete(foo); // 从set中删除 foo 对象,然后返回一个false
ws.has(foo); // false, foo 对象已经被删除了
ws.has(bar); // true, bar 依然存在
foo !== bar。 尽管它们是相似的对象,但是它们不是*同一个对象。 *因此,它们都可以被加入到set中。
Set
1.成员不能重复
2.只有健值,没有健名,有点类似数组。
3. 可以遍历,方法有add, delete,has
weakSet
1.成员都是对象
2. 成员都是弱引用,随时可以消失。 可以用来保存DOM节点,不容易造成内存泄漏
3. 不能遍历,方法有add, delete,has
Map
1.本质上是健值对的集合,类似集合
2.可以遍历,方法很多,可以干跟各种数据格式转换