关于Set、Map、WeakSet、WeakMap的二三事

1.Set

特征:

  1. 成员不能重复
  2. 只有键值,没有键名,有点类似于数组
  3. 可以遍历

console.log(Set.prototype)

对于Set应该明确的几点:

⭐ 不重复
在js中判断元素相等的方法有两种:===Object.is

1
2
3
4
5
NaN === NaN  // false
Object.is(NaN , NaN) // true

+0 === -0 // true
Object.is(+0 , -0) // false

我们不妨来看一下,Set遵循哪种原则呢?

1
2
3
4
5
6
7
var set = new Set();
set.add(1);
set.add(NaN);
set.add(NaN);
set.add(0);
set.add(-0);
console.log(set);

可以看到,在Set中,认为NaN是相等的,认为+0-0也是相等的,所以才会说Set中成员是不重复的。

⭐ 数组 ⇌ Set

数组转换为Setnew Set([1,2,3])

Set转换为数组:[...set]

2.WeakSet

特征:

  1. 成员都是对象(Object或者继承自Object的类型),尝试其他值会抛出TypeError
  2. WeakSet是弱引用,随时可以消失(不计入垃圾回收机制)。可以用来保存DOM节点,不容易造成内存泄漏
  3. 不能遍历

console.log(WeakSet.prototype)

对于WeakSet需要明确几点:

⭐ 何为 强引用 & 弱引用?

对于一个全局变量var key = {},JS垃圾回收器不能自动将其回收,若想要释放内存,则需让 key = null

※ 强引用

1
2
3
4
5
let cat = { name: "Kitty" };
const pets = [cat];

cat = null;
console.log(pets); // [{ name: "Kitty" }]

通过将变量 cat 创建为对象,并把这个对象放入一个数组 pets 中,然后通过将它的值设置为 null 来删除其对原始对象的引用。

尽管我们再也无法访问 cat 变量,但由于在 pets 数组和这个对象之间存在强引用关系,因此这个对象其实仍保留在内存中,并且可以通过 pets[0] 访问到它。 换句话说,强引用可以防止垃圾回收从内存中删除对象。

※ 弱引用

弱引用是对对象的引用,如果它还是对内存中对象的唯一引用,就能顺利地进行垃圾回收。相反,一般强引用都会防止垃圾回收。

1
2
3
4
5
6
7
8
let pets = new WeakMap();
let cat = { name: "Kitty" };
pets.set(cat, "Kitty");
console.log(pets); // WeakMap {{…} => 'Kitty'}
cat = null;

// 等待垃圾回收后
console.log(pets); // WeakMap{}

通过利用 WeakMap 及其附带的弱引用,我们可以看到两种类型的引用之间的差异。虽然对原始 cat 对象的强引用仍然存在,但 cat 对象仍然存在于 WeakMap 中,我们可以毫无问题地访问它。

但是,当我们通过将 cat变量重新赋值 null 来覆盖对原始 cat 对象的引用时,由于内存中对原始对象的唯一引用是来自我们创建的 WeakMap 的弱引用,所以它不会阻止垃圾回收的发生。这意味着当 JavaScript 引擎再次运行垃圾回收过程时,cat 对象将从内存和我们分配给它的 WeakMap 中删除。

因此这里的关键区就别在于,强引用可以防止对象进行垃圾回收,而弱引用则不会。

默认情况下,JavaScript 对其所有引用使用强引用,使用弱引用的唯一方法是使用 WeakMap 或 WeakSet。

3.Map

特征:

  1. 本质上是键值对
  2. 可以遍历

Q:ObjectMap的区别?

  • 键的类型:Object的key值必须是StringNumber或者SymbolMap的键可以是JavaScript支持的所有类型。
  • 元素顺序:Map 元素的顺序遵循插入的顺序,而 Object 的则没有这一特性。
  • 继承:Map 继承自 Object 对象。

4.WeakMap

文章作者: qinwei
文章链接: https://qw-null.github.io/2022/04/25/关于Set、Map、WeakSet、WeakMap的二三事/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 QW's Blog