了解WeakSet,还有它的一些使用

233

这是我参与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.可以遍历,方法很多,可以干跟各种数据格式转换