首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么使用WeakSet来检测循环引用是有意义的?

为什么使用WeakSet来检测循环引用是有意义的?
EN

Stack Overflow用户
提问于 2021-11-21 19:37:58
回答 1查看 80关注 0票数 1

我正在尝试理解WeakSet文档这里给出的示例。

代码语言:javascript
复制
// Execute a callback on everything stored inside an object
function execRecursively(fn, subject, _refs = null){
  if(!_refs)
    _refs = new WeakSet();

  // Avoid infinite recursion
  if(_refs.has(subject))
    return;

  fn(subject);
  if("object" === typeof subject){
    _refs.add(subject);
    for(let key in subject)
      execRecursively(fn, subject[key], _refs);
  }
}

const foo = {
  foo: "Foo",
  bar: {
    bar: "Bar"
  }
};

foo.bar.baz = foo; // Circular reference!
execRecursively(obj => console.log(obj), foo);

医生里写着:

WeakSet是弱的,这意味着对WeakSet中的对象的引用是弱保持的。如果不存在对存储在WeakSet中的对象的其他引用,则可以垃圾收集这些对象。

对象foo是在execRecursively函数之外定义的。WeakSet是在其中定义的。因此,有一个对保存在Weakset中的对象的引用,它超出了函数的范围。

医生接着说:

对象的数量或它们的遍历顺序并不重要,因此WeakSet比一组跟踪对象引用更适合(和性能),特别是在涉及大量对象的情况下。

现在,我的问题是,与使用Set时相比,这段代码如何具有更高的性能?因为,即使在当前示例中,也有对foo的引用,它阻止垃圾收集器移除对象。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-21 20:05:05

这段代码怎么能比使用Set时性能更好呢?

就像文档说的那样,WeakSet不跟踪对象的数量或它们在集合中放置的顺序,所以开销会稍微小一些。

在当前的示例中,有一个对foo的引用,它阻止垃圾收集器移除对象。

是的,但是这是特定于你的例子。只有当对象在遍历结构时懒洋洋地生成时,弱点才会变得有趣(并且有用)。请参见以下示例:

代码语言:javascript
复制
function generate(n) {
    if (n <= 0) return foo;
    else return {
        value: "x".repeat(n),
        get next() { return generate(n-1); },
    }
}
const foo = generate(100000);
let sum = 0;
execRecursively(obj => { sum += obj.value.length, foo);
console.log(sum);

如果execRecursively使用一个Set,那么在执行过程中,它需要保留10万个对象,这些对象在内存中包含非常长的字符串。当使用WeakSet时,在执行过程中已经可以垃圾收集对象了。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70057967

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档