日常学习2024.03.12-js中的weakSet

news/2024/7/24 9:30:54 标签: javascript, 学习, 前端

日常学习2024.03.12-js中的weakSet

  • 1.WeakSet是什么?
  • 2.WeakSet 使用弱引用,Set使用强引用

1.WeakSet是什么?

weakSet是什么呢?刚开始自己确实也没什么印象,终结学习一下吧。

WeakSet 是可被垃圾回收的值的集合,包括对象和非全局注册的符号(Symbol基本数据类型)。WeakSet 中的值只能出现一次。它在 WeakSet 的集合中是唯一的。

WeakSet 中的值一定是可被垃圾回收的值。大多数原始数据类型可以被任意地创建,并且没有生命周期,所以它们不能被存储。对象和非全局注册的符号可以被存储,因为它们是可被垃圾回收的值。

它和 Set 对象的主要区别有:

WeakSet 只能是对象和符号的集合,它不能像 Set 那样包含任何类型的任意值。
WeakSet 持弱引用:WeakSet 中对象的引用为弱引用。如果没有其他的对 WeakSet 中对象的引用存在,那么这些对象会被垃圾回收。

第一个区别好理解

javascript">const ws = new WeakSet();
ws.add(1) // 报错,Uncaught TypeError: Invalid value used in weak set
ws.add(Symbol()) // 不报错

第二个区别就有点懵了

2.WeakSet 使用弱引用,Set使用强引用

WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakSet 之中。

这是因为垃圾回收机制根据对象的可达性(reachability)来判断回收,如果对象还能被访问到,垃圾回收机制就不会释放这块内存。结束使用该值之后,有时会忘记取消引用,导致内存无法释放,进而可能会引发内存泄漏。WeakSet 里面的引用,都不计入垃圾回收机制,所以就不存在这个问题。因此,WeakSet 适合临时存放一组对象,以及存放跟对象绑定的信息。只要这些对象在外部消失,它在 WeakSet 里面的引用就会自动消失。

由于上面这个特点,WeakSet 的成员是不适合引用的,因为它会随时消失。另外,由于 WeakSet 内部有多少个成员,取决于垃圾回收机制有没有运行,运行前后很可能成员个数是不一样的,而垃圾回收机制何时运行是不可预测的,因此 ES6 规定 WeakSet 不可遍历。

举个例子

javascript">let weakSet = new WeakSet();

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

// 将对象添加到 WeakSet 中
weakSet.add(obj1);
weakSet.add(obj2);

console.log(weakSet.has(obj1)); // true
console.log(weakSet.has(obj2)); // true

// 移除对 obj1 的引用
obj1 = null;

// 在这里,obj1 不再有任何强引用,可以被垃圾回收

console.log(weakSet.has(obj1)); // false
console.log(weakSet.has(obj2)); // true```

在上述示例中,我们创建了一个 WeakSet 实例 weakSet,并将两个对象 obj1 和 obj2 添加到其中。我们可以使用 has 方法检查对象是否存在于 WeakSet 中。

随后,我们将 obj1 的引用设置为 null,从而删除了对它的强引用。此时,obj1 不再有任何强引用,因此它可以被垃圾回收。

在最后的两个 console.log 语句中,我们可以看到 weakSet.has(obj1) 返回 false,表示 obj1 已经从 WeakSet 中被移除。而对于 obj2,它仍然存在于 WeakSet 中,因为它仍有一个强引用。

但是如果将WeakSet换成Set呢

javascript">let et = new Set();

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

// 将对象添加到 WeakSet 中
et.add(obj1);
et.add(obj2);

console.log(et.has(obj1)); // true
console.log(et.has(obj2)); // true

// 移除对 obj1 的引用
obj1 = null;
console.log(et.has(obj1)); // false
console.log(et.has(obj2)); // true

结果还是一样的!那Set和WeakSet的第二个区别不就没有区别了吗。其实不是的
在上面的代码中,即使我们将 obj 设置为 null,Set 中的对象仍然不会被垃圾回收,因为 Set 本身保持了对它的强引用。如果我们试图检查 set.has(obj),由于 obj 是 null,这个检查没有意义。要正确检查 Set 是否包含对象,我们需要一个有效的引用到那个对象,这在我们的例子中是不存在的。
改一下代码

javascript">// 创建一个对象  
let obj1 = { name: "Example1" };  
  
// 创建一个 Set 并将对象添加进去  
let set = new Set();  
set.add(obj1);  
  
// 此时,set 包含了对 obj1 的强引用  
  
// 创建另一个引用,指向同一个对象  
let obj2 = obj1;  
  
// 移除 obj1 引用,但 obj2 仍然引用着对象  
obj1 = null;  
  
// 使用 obj2 检查对象是否仍然在 set 中  
console.log(set.has(obj2)); // 输出 true,因为 obj2 仍然引用着对象,且对象在 set 中  
  
// 现在,如果我们没有其他引用指向对象,并且尝试重新构造一个看似相同的对象,  
// 它将不会被视为同一个对象,因为对象在 JavaScript 中是通过引用比较的  
let obj3 = { name: "Example1" }; // 这是一个新的对象,与之前的 obj1 不是同一个引用  
  
console.log(set.has(obj3)); // 输出 false,因为 obj3 是一个新的对象,尽管它的内容看起来与 set 中的对象相同

这个例子就能说明WeakSet 使用弱引用,这意味着如果没有其他强引用指向对象,对象可以被垃圾回收;而 Set 使用强引用,即使没有其他变量引用对象,Set 也会保持对象不被回收。
好好理解下,如果有问题欢迎指出


http://www.niftyadmin.cn/n/5425442.html

相关文章

柔性数组(变长数组)介绍

柔性数组简介 柔性数组,或称为可变长度数组,是一种在C语言结构体定义中使用的特殊数组,它允许结构体拥有一个可变大小的数组成员。柔性数组成员必须是结构体的最后一个成员,且它不占用结构体大小的计算,这使得可以动态…

数据结构之树(Topk问题, 链式二叉树)

一.topk问题 取N个数中最大(小)的前k个值,N远大于k 这道题可以用堆的方法来解决,首先取这N个数的前k个值,用它们建堆 时间复杂度O(k) 之后将剩余的N-k个数据依次与堆顶数据进行比较,如果比堆顶数据大,则将堆顶数据覆盖后向下调整 时间复杂度(N-k)*log(N) 总共的时间复杂度…

C语言malloc动态内存开辟

由于各种原因,然后一个多星期没有学习过C语言了,然后就也没有进行更新,今天开始继续学习C语言,然后下面是使用malloc开辟动态内存的一个例子:我想大家都应该可以看明白。 #define _CRT_SECURE_NO_WARNINGS 1#include…

c#递归函数

在 C#中,递归函数是指在函数内部直接或间接调用自身的函数。递归函数在解决一些问题时非常有用,例如遍历树形结构、递归计算等。 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的木材表面缺陷检测系统(深度学习+Python代码+UI界面+训练数据集)

摘要:开发高效的木材表面缺陷检测系统对于提升木材加工行业的质量控制和生产效率至关重要。本篇博客详细介绍了如何运用深度学习技术构建一个木材表面缺陷检测系统,并提供了完整的实现代码。该系统采用了强大的YOLOv8算法,并对YOLOv7、YOLOv6…

【RepVGG网络】

RepVGG网络 RepVGG网络是2021年由清华大学、旷视科技与香港科技大学等机构的研究者提出的一种深度学习模型结构,其核心特点是通过“结构重参数化”(re-parameterization)技术,在训练阶段采用复杂的多分支结构以优化网络的训练过程…

基于SpringBoot的“逍遥大药房管理系统”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“逍遥大药房管理系统”的设计与实现(源码数据库文档PPT) 开发语言:Java 数据库:MySQL 技术:SpringBoot 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 系统首页界面图 药品信息界面图 疫情常识界…

【力扣刷题】Leetcode 2592 最大化数组的伟大值

文章目录 1. Leetcode 2592 最大化数组的伟大值 1. Leetcode 2592 最大化数组的伟大值 题目链接 本题思考的关键点:① nums 的最小值要参与匹配,否则更大的数字更难匹配上;② nums 最小值要与次小值进行比较,这样才能贡献值最大…