• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • WeakSet

    WeakSet对象允许你将弱保持对象存储在一个集合中。

    描述

    WeakSet对象是一些对象值的集合。且其与Set类似,WeakSet中的每个对象值都只能出现一次。在WeakSet的集合中,所有对象都是唯一的。

    它和Set对象的主要区别有:

    • WeakSet只能是对象的集合,而不能像Set那样,可以是任何类型的任意值。
    • WeakSet弱引用:集合中对象的引用为引用。如果没有其它的对WeakSet中对象的引用,那么这些对象会被当成垃圾回收掉。

    备注:这也意味着WeakSet中没有存储当前对象的列表。正因为这样,WeakSet是不可枚举的。

    用例:检测循环引用

    递归调用自身的函数需要一种通过跟踪哪些对象已被处理,来应对循环数据结构的方法。

    为此,WeakSet非常适合处理这种情况:

    // 对 传入的 subject 对象 内部存储的所有内容执行回调
    function execRecursively(fn, subject, _refs = new WeakSet()) {
      // 避免无限递归
      if (_refs.has(subject)) {
        return;
      }
    
      fn(subject);
      if (typeof subject === "object") {
        _refs.add(subject);
        for (const key in subject) {
          execRecursively(fn, subject[key], _refs);
        }
      }
    }
    
    const foo = {
      foo: "Foo",
      bar: {
        bar: "Bar",
      },
    };
    
    foo.bar.baz = foo; // 循环引用!
    execRecursively((obj) => console.log(obj), foo);
    
    Copy to Clipboard

    在此,在第一次运行时创建WeakSet,并将其与每个后续函数调用一起传递(使用内部参数_refs)。

    对象的数量或它们的遍历顺序无关紧要,因此,WeakSetSet更适合(和执行)跟踪对象引用,尤其是在涉及大量对象时。

    构造函数

    WeakSet()(en-US)

    创建一个新的WeakSet对象。

    实例方法

    WeakSet.prototype.add(value)

    value添加到WeakSet对象最后一个元素的后面。

    WeakSet.prototype.delete(value)

    WeakSet中移除value。此后调用WeakSet.prototype.has(value)将返回false

    WeakSet.prototype.has(value)

    返回一个布尔值,表示value是否存在于WeakSet对象中。

    示例

    使用 WeakSet 对象

    const ws = new WeakSet();
    const foo = {};
    const bar = {};
    
    ws.add(foo);
    ws.add(bar);
    
    ws.has(foo);    // true
    ws.has(bar);    // true
    
    ws.delete(foo); // 从 set 中删除 foo 对象
    ws.has(foo);    // false,foo 对象已经被删除了
    ws.has(bar);    // true,bar 依然存在
    
    Copy to Clipboard

    注意,foo !== bar。尽管它们是相似的对象,但是它们不是**同一个对象**。因此,它们都可以被加入到 set 中。

    下篇:new WeakSet()