🔥🔥当面试官问:你能聊聊set和weakSet的区别吗(阿里面试题)

255 阅读4分钟

前言

大家上午好,这里是知了,今天我们讲讲非常多大厂面试会问到的一个面试题:请你聊聊set和weakSet的区别

setWeakSet 都是 ECMAScript 6(ES6)中引入的语法特性,用于表示集合(Set)和弱引用的集合(WeakSet)。它们是 ES6 中新增的数据结构,为 JavaScript 提供了更灵活和强大的集合管理工具。

在过去的几年里,ES6 的推出标志着JavaScript语言的一次革命,为开发者提供了许多强大的新功能和语法糖。如果大家想要了解ES6的39条特性汇总的话,可以看看这位大佬的文章,总结的非常细致==> [ES6+新特性全面汇总39条 - Yiko的专栏 - 掘金 (juejin.cn)]

引入

在我们开始了解set和weakSet的区别之前,我们要先了解强引用弱引用

弱引用和强引用是在垃圾回收(Garbage Collection)过程中用于管理内存的概念。它们主要涉及到对象的引用计数,用于决定何时可以释放不再被引用的内存。

强引用(Strong Reference)

  • 定义: 强引用是指对对象的引用,这个引用会阻止对象被垃圾回收。只要存在强引用,垃圾回收器就不会回收相应的对象。

  • 示例: 使用变量、属性、数组元素等方式创建的引用都是强引用。

    let obj = { data: 'Hello' }; // 强引用
    let arr = [obj]; // 强引用
    
  • 影响: 当对象不再被任何强引用引用时,垃圾回收器会将其标记为可回收,并在合适的时机释放其占用的内存。

弱引用(Weak Reference)

  • 定义: 弱引用是一种对对象的引用,不会阻止对象被垃圾回收。如果一个对象只有弱引用指向它,那么它就可能被垃圾回收,即使程序中还有对该对象的弱引用存在。

  • 示例: 使用 WeakMapWeakSet 等数据结构创建的引用是弱引用。

    let weakMap = new WeakMap();
    let obj = { data: 'Hello' };
    weakMap.set(obj, 'World'); // 弱引用
    
  • 影响: 当对象只有弱引用时,垃圾回收器可能会在对象没有强引用时将其回收。弱引用通常用于在不影响垃圾回收的情况下存储一些临时性的关联数据。

总结

  • 强引用:

    • 阻止对象被垃圾回收。
    • 使用变量、属性、数组元素等方式创建的引用都是强引用。
  • 弱引用:

    • 不阻止对象被垃圾回收。
    • 使用 WeakMapWeakSet 等数据结构创建的引用是弱引用。

在开发中,对于一些临时性的引用关系,特别是需要在对象不再被强引用时自动释放的场景,使用弱引用可以更好地管理内存,避免内存泄漏问题。

区别1. 主要用途

  • Set 用于存储任意类型的值,包括原始值和对象引用。Set 中的元素是强引用,即使在其他地方没有引用,Set 中的值也不会被垃圾回收。

    const set = new Set();
    const obj = {};
    
    set.add(obj);
    console.log(set.has(obj)); // true
    
    // 如果不再引用 obj
    obj = null;
    
    console.log(set.has(obj)); // true(由于Set中仍然存在对obj的引用,obj并未被垃圾回收)
    
  • WeakSet 用于存储对象引用。WeakSet 中的元素是弱引用,如果在其他地方没有对对象的引用,那么该对象可能会被垃圾回收并从 WeakSet 中移除。

    const weakSet = new WeakSet();
    let obj = {};
    
    weakSet.add(obj);
    console.log(weakSet.has(obj)); // true
    
    // 如果不再引用 obj
    obj = null;
    
    console.log(weakSet.has(obj)); // false(obj 已被垃圾回收并从 WeakSet 中移除)
    

区别2. 元素类型

  • Set 可以包含任意类型的值,包括原始值和对象引用。

    const set = new Set();
    set.add(1).add('hello').add({ name: 'John' });
    
  • WeakSet 只能包含对象引用,不能包含原始值。

    const weakSet = new WeakSet();
    const obj1 = {};
    const obj2 = {};
    
    weakSet.add(obj1);
    weakSet.add(obj2);
    

区别3. 迭代和清空

  • Set 提供了迭代方法(forEach, values, entries 等)以及 clear() 方法用于清空所有元素。

    const set = new Set([1, 2, 3]);
    
    for (let item of set) {
      console.log(item);
    }
    
    set.clear();
    
  • WeakSet 由于弱引用的特性,WeakSet 不提供迭代方法,也没有 clear() 方法,因此不能遍历其中的元素,也不能直接清空 WeakSet

区别4. 大小属性

  • Setsize 属性,可以获取集合中元素的数量。

    const set = new Set([1, 2, 3]);
    console.log(set.size); // 3
    
  • WeakSet 没有 size 属性,也没有类似的方法来获取集合中元素的数量。

区别5. 应用场景

  • Set 适用于需要存储一组唯一值,并且需要遍历和清空的场景。
  • WeakSet 适用于需要存储一组对象引用,且不需要遍历和清空的场景。在实际应用中,WeakSet 主要用于对象存储的辅助数据结构,而不是主要数据存储。

总体来说,SetWeakSet 在实际使用中有不同的适用场景,根据需求选择合适的数据结构。

结语

那么我们今天的内容就结束啦,欢迎各路大神在评论区讨论~~

点赞收藏不迷路,咱们下次再见ヾ( ̄▽ ̄)ByeBye~