ES6 Set 和 WeakSet 有什么区别?

30

ECMAScript 6引入了两种非常相似的集合类型:SetWeakSet。它们之间有什么区别呢?


可能是ES6 Set、WeakSet、Map 和 WeakMap的重复问题。 - a better oliver
5个回答

31

主要的不同点在于,Set中对对象的引用是强引用,而WeakSet中对对象的引用是弱引用。这意味着如果没有其他引用指向WeakSet中的对象,该对象可能会被垃圾回收

其他区别(或副作用)包括:

  • Sets可以存储任何值,而WeakSets仅限于对象。
  • WeakSet没有size属性。
  • WeakSet没有clear、keys、values、entries、forEach等方法。
  • WeakSet不可迭代。

1
还有其他的区别吗?比如内存使用、性能方面的差异? - evolutionxbox
2
WeakSet不可迭代,那么我们为什么要使用它,以及如何解析它? - Vikas Bansal
10
WeakSet 允许你在 O(1) 时间内检查任何对象是否已经被添加进去。你可以将其用作布尔值检查对象,例如用于记忆化方法的情况下。另一个好处是,如果对象超出范围,不像普通的 Set 会浪费内存,因为它可以被垃圾回收。 - Patrick Roberts

11

摘要:

WeakSet是JavaScript对象,用于保存对象的集合。由于集合的性质,只能在集合中出现同一对象的一个对象引用。WeakSet与普通集合的不同之处在于:

  1. WeakSet只能保存其集合中的对象,不能保存基本值(例如intbooleanstring)。
  2. 对对象的引用是弱引用的。这意味着,除了WeakSet之外没有其他引用指向该对象时,对象可以被垃圾收集(即JS引擎将释放对象引用所指向的内存)。

示例:

let myWeakSet = new WeakSet();
let obj = {};
myWeakSet.add(obj); 
console.log(myWeakSet.has(obj));

// break the last reference to the object we created earlier
obj = 5;

// false because no other references to the object which the weakset points to
// because weakset was the only object holding a reference it released it and got garbage collected
console.log(myWeakSet.has(obj)); 
                     


1
在你的示例中使用 Set 而不是 WeakSet 将产生相同的结果! - Saman Mohamadi
1
此刻,myWeakSet不包含对obj的引用,因为obj指向一个原始值5。这并没有说明WeakSet的弱引用行为。 - Spike Sagal
WeakSet允许您在O(1)时间内进行搜索,而Set需要O(n)时间。因此,在数组中搜索对象时,首选WeakSet,但在这个不可变的时代,谁会想要做这样的事情呢...为什么不采用更安全的不可变性选项呢? - Ankit Tanna

4

Set(集合):是一组值的集合,其中每个值只能出现一次。主要方法有add(添加)、delete(删除)、has(是否存在)、clear(清空)和size(大小)。

WeakSet(弱集合):WeakSet对象允许您存储一组唯一的键。"WeakSet"键不能是原始类型。它们也不能由数组或另一个集合创建。WeakSet的值必须是对象引用。


你的回答不够清晰。我尝试改进了它,但我仍然认为关于WeakSet缺少信息。 - Marco Altieri

1
  • Sets允许只存储一次。
  • 存储在集合中的元素没有键或索引。因此,使用默认方法(如get())检索元素很困难。
  • WeakSet仅接受对象作为其值。
  • 如果没有其他对存储的对象的引用(引用是弱的),则weakset不会阻止垃圾收集。

0
example will be more clear if written like this :
   
     let myWeakSet = new WeakSet();
     let x = {name:"ali",age:38};
     myWeakSet.add(x);
     x = 5; 
     console.log(myWeakSet);

then:
     let mySet = new Set();
     let x = {name:"ali",age:38};
     mySet.add(x);
     x = 5; 
     console.log(mySet);
    
in the first example console will show you that weakSet contain no objects because another value was assigned to object reference (x) ......but in second example console will show you that Set contain an object ... and by making mySet iterable you can see the properties of object(x) you have added to mySet :

     console.log(mySet.values().next().value);

我想感谢@Willem van der Veen,因为我使用了他的示例来解释我的想法。 - TAREK KOTB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接