set和weakSet中强引用和弱引用

Set 和 WeakSet 都保存对对象(如 obj1)的引用,但它们处理这些引用的方式不同,这直接影响到垃圾回收的行为。

set中任何类型都可以存储,但是weakSet只能存储对象和Symbol类型的数据。

强引用 vs. 弱引用

  • 强引用:当一个对象被 Set 引用时,Set 持有的是对该对象的强引用。这意味着只要 Set 存在并且包含这个对象,JavaScript 的垃圾回收机制就不会回收这个对象,即使没有其他的变量引用它。因此,Set 中的对象会一直存在,直到你显式地从 Set 中删除它或者清空 Set

  • 弱引用WeakSet 持有的是对象的弱引用。如果一个对象只被 WeakSet 引用而没有其他强引用,那么这个对象可能会在任何时候被垃圾回收。WeakSet 不会阻止垃圾回收器回收这些对象,因此一旦对象不再有强引用,它就可能被移除并回收。

示例

让我们通过一个具体的例子来说明这两种行为:

// 创建两个对象
const obj1 = { name: 'Object 1' };
const obj2 = { name: 'Object 2' };

// 创建 Set 和 WeakSet 实例
const mySet = new Set();
const myWeakSet = new WeakSet();

// 将 obj1 和 obj2 分别添加到 Set 和 WeakSet 中
mySet.add(obj1);
myWeakSet.add(obj2);

// 清除 obj1 和 obj2 的所有外部引用
obj1 = null;
obj2 = null;

// 在这里,你可以使用浏览器的开发者工具或 Node.js 环境中的 gc() 函数来尝试触发垃圾回收。
if (global.gc) {
    global.gc(); // 手动触发垃圾回收(仅在某些环境中有效)
}

// 检查垃圾回收后的状态
setTimeout(() => {
    console.log('After attempting garbage collection:');
    
    // 对于 Set,obj1 仍然存在,因为它持有强引用
    console.log('Set size:', mySet.size); // 输出 1 或 0,取决于垃圾回收是否发生
    for (let item of mySet) {
        console.log('Set contains:', item.name); // 如果 obj1 还未被回收,输出 "Object 1"
    }

    // 对于 WeakSet,obj2 可能已经被垃圾回收,因为它只持有弱引用
    console.log('WeakSet has obj2:', myWeakSet.has(obj2)); // 输出 false,因为 obj2 已经被设置为 null
}, 0);

解释

  • Set 的行为

    • obj1 被添加到 Set 中后,Set 持有对 obj1 的强引用。
    • 即使我们将 obj1 设置为 nullSet 仍然持有对原始对象的强引用,因此这个对象不会被垃圾回收。
    • 如果我们遍历 Set,我们仍然可以看到 obj1 的内容(前提是垃圾回收尚未发生)。
  • WeakSet 的行为

    • obj2 被添加到 WeakSet 中后,WeakSet 持有对 obj2 的弱引用。
    • 当我们将 obj2 设置为 null 时,obj2 没有其他强引用,因此它可以被垃圾回收。
    • 垃圾回收发生后,WeakSet 中的 obj2 会被自动移除,myWeakSet.has(obj2) 会返回 false

关键点

  • Set:持有强引用,防止对象被垃圾回收,直到你显式地从 Set 中删除对象或清空 Set
  • WeakSet:持有弱引用,允许对象在没有其他强引用时被垃圾回收,WeakSet 会自动移除这些对象。

总结

  • Set 适合用于需要持久化存储对象的场景,确保对象不会被意外回收。
  • WeakSet 适合用于临时关联数据或实现某种形式的私有化机制,避免内存泄漏,尤其是在你不希望对象长时间存在于内存中的情况下。

通过这种方式,你可以根据具体的需求选择合适的集合类型,以优化内存管理和数据结构的设计。

WeakSet不会阻止垃圾回收对象,只要这个对象没被任何地方强引用了,垃圾回收就会回收对象,不会去管WeakSet是否还用着这个对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值