前端深入理解JavaScript中的WeakMap和WeakSet

 🎬 岸边的风:个人主页

 🔥 个人专栏 :《 VUE 》 《 javaScript 》

⛺️ 生活的理想,就是为了理想的生活 !

在这里插入图片描述

目录

1. WeakMap和WeakSet概述

1.1 WeakMap

1.2 WeakSet

2. WeakMap深入解析

2.1 WeakMap的创建和使用

2.2 WeakMap和内存管理

2.3 WeakMap和对象私有数据

3. WeakSet深入解析

3.1 WeakSet的创建和使用

3.2 WeakSet和对象唯一性

3.3 WeakSet和内存管理

4. 结论


 

 

在JavaScript的ES6版本中,引入了两种新的数据结构——WeakMapWeakSet。与Map和Set相比,这两种数据结构有一些特殊的特点和用途,因此在某些场合下,它们是更好的选择。本文将深入探讨WeakMapWeakSet的特性和用途。

1. WeakMap和WeakSet概述

在我们深入研究这两种新的数据结构之前,首先来了解一下它们的基本特性。

1.1 WeakMap

WeakMap是一种键值对的集合,类似于Map。不过,WeakMapMap有几个重要的区别:

  • WeakMap中,只有对象可以作为键。换句话说,我们不能使用基本类型(如数字,字符串,布尔值等)作为WeakMap的键。
  • WeakMap的键是弱引用的。这意味着,如果一个对象只被WeakMap引用,那么这个对象可以被垃圾回收(GC)。当这个对象被垃圾回收后,它对应的键值对也会从WeakMap中自动移除。
  • WeakMap不可遍历,也就是说,我们不能使用像for...of这样的循环来遍历WeakMap

由于这些特性,WeakMap在处理内存泄漏问题和管理对象私有数据等场景中有着显著的优势。

1.2 WeakSet

WeakSet也是一种集合,类似于SetWeakSetSet的主要区别包括:

  • WeakSet中,只有对象可以作为值。也就是说,我们不能将基本类型(如数字,字符串,布尔值等)添加到WeakSet中。
  • WeakSet中的对象是弱引用的。如果一个对象只被WeakSet引用,那么这个对象可以被垃圾回收。当这个对象被垃圾回收后,它会自动从WeakSet中移除。
  • WeakSet不可遍历,也就是说,我们不能使用像for...of这样的循环来遍历WeakSet

WeakSet在处理对象的唯一性、内存泄漏等问题上有其独特的应用。

2. WeakMap深入解析

下面,我们将更深入地探讨WeakMap的特性和用法。

2.1 WeakMap的创建和使用

我们可以使用new WeakMap()来创建一个新的WeakMap。在创建了WeakMap之后,我们可以使用set方法来添加新的键值对,

使用get方法来获取某个键对应的值,使用delete方法来移除某个键及其对应的值,使用has方法来检查WeakMap中是否存在某个键。

let weakMap = new WeakMap();let obj1 = {};
let obj2 = {};// 添加键值对
weakMap.set(obj1, 'Hello');
weakMap.set(obj2, 'World');// 获取值
console.log(weakMap.get(obj1)); // 输出: 'Hello'
console.log(weakMap.get(obj2)); // 输出: 'World'// 检查键是否存在
console.log(weakMap.has(obj1)); // 输出: true
console.log(weakMap.has(obj2)); // 输出: true// 删除键值对
weakMap.delete(obj1);
console.log(weakMap.has(obj1)); // 输出: false

2.2 WeakMap和内存管理

WeakMap最重要的特性就是其键对对象的弱引用。这意味着,如果一个对象只被WeakMap引用,那么这个对象可以被垃圾回收。这样就可以防止因为长时间持有对象引用导致的内存泄漏。

例如,如果我们在Map中保存了一些对象的引用,即使这些对象在其他地方都已经不再使用,但是由于它们仍被Map引用,所以它们不能被垃圾回收,这就可能导致内存泄漏。然而,如果我们使用WeakMap来保存这些对象的引用,那么当这些对象在其他地方都不再使用时,它们就会被垃圾回收,从而防止了内存泄漏。

2.3 WeakMap和对象私有数据

WeakMap还常常被用来保存对象的私有数据。这是因为WeakMap的键不可遍历,所以我们可以利用这个特性来存储一些只有特定代码能够访问的数据。

例如,我们可以创建一个WeakMap,然后使用这个WeakMap来保存每个对象的私有数据,像这样:

let privateData = new WeakMap();function MyClass() {privateData.set(this, {secret: 'my secret data',});
}MyClass.prototype.getSecret = function() {return privateData.get(this).secret;
};let obj = new MyClass();
console.log(obj.getSecret()); // 输出: 'my secret data'

在这个例子中,我们创建了一个MyClass的类,每一个MyClass的实例都有一个私有数据secret。我们使用WeakMap来保存这个私有数据。这样,我们就可以在MyClass的方法中访问这个私有数据,但是其他的代码无法访问它。

3. WeakSet深入解析

接下来,我们将更深入地探讨WeakSet的特性和用法。

3.1 WeakSet的创建和使用

我们可以使用new WeakSet()来创建一个新的WeakSet。在创建了WeakSet之后,我们可以使用add方法来添加新的对象,使用delete方法来移除某个对象,使用has方法来检查WeakSet中是否存在某个对象。

let weakSet = new WeakSet();let obj1 = {};
let obj2 = {};// 添加对象
weakSet.add(obj1);
weakSet.add(obj2);// 检查对象是否存在
console.log(weakSet.has(obj1)); // 输出: true
console.log(weakSet.has(obj2)); // 输出: true// 删除对象
weakSet.delete(obj1);
console.log(weakSet.has(obj1)); // 输出: false

3.2 WeakSet和对象唯一性

WeakSet可以用来检查一个对象是否已经存在。由于WeakSet中的每个对象都是唯一的,所以我们可以利用这个特性来确保我们不会添加重复的对象。

例如,我们可以创建一个WeakSet,然后使用这个WeakSet来保存所有我们已经处理过的对象,像这样:

let processedObjects = new WeakSet();function processObject(obj) {if (!processedObjects.has(obj)) {// 处理对象// ...// 将对象添加到WeakSet中,表示我们已经处理过这个对象processedObjects.add(obj);}
}

在这个例子中,我们在每次处理一个对象之前,都会检查这个对象是否已经被处理过。如果这个对象已经被处理过,我们就不会再处理它。这样,我们就可以确保我们不会重复处理同一个对象。

3.3 WeakSet和内存管理

WeakMap一样,WeakSet中的对象也是弱引用的,所以WeakSet也有优秀的内存管理特性。如果一个对象只被WeakSet引用,那么这个对象可以被垃圾回收。这样就可以防止因为长时间持有对象引用导致的内存泄漏。

例如,如果我们在Set中保存了一些对象的引用,即使这些对象在其他地方都已经不再使用,但是由于它们仍被Set引用,所以它们不能被垃圾回收,这就可能导致内存泄漏。然而,如果我们使用WeakSet来保存这些对象的引用,那么当这些对象在其他地方都不再使用时,它们就会被垃圾回收,从而防止了内存泄漏。

4. 结论

在JavaScript的ES6版本中,引入了WeakMapWeakSet这两种新的数据结构。与MapSet相比,它们有一些特殊的特点和用途,使它们在处理内存泄漏问题、管理对象私有数据、处理对象的唯一性等场景中有显著的优势。理解它们的特性和用法,可以帮助我们更有效地使用JavaScript来编写高效、稳定的代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/132569.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软件流程图怎么画?详细画法看这里

软件流程图怎么画?软件流程图是软件开发过程中必不可少的一环,可以帮助开发人员更好地理解和规划软件开发的流程。在制作软件流程图的时候,我们可以使用一些制作工具。下面就给大家介绍一款好用的绘制工具。 我们可以使用【迅捷画图】来进行流…

Android端Base64解码表情emoj乱码

一、背景:H5端用户评论中包含表情包,通过JSBridge 传递给客户端,Android Base64解码之后,显示乱码(是菱形问号)。小程序和iOS可以正常解码出表情。用Base64在线编码解码(Base64 在线编码解码 | …

BOM操作

文章目录 BOM事件页面加载调整窗口事件定时器停止计时器Location对象History对象Offsetleft获取元素偏移Offset与style的区别可视区client系列滚动scroll系列Mouseover和mousenter区别 动画原理实现动画封装给不同对象添加定时器缓动动画原理多个位置间移动 BOM事件 页面加载 …

BeanUtils.copyProperties的使用场景

1. 常见场景 我们如果有两个具有很多相同属性名的JavaBean对象a和b,想把a中的属性赋值到b,例如 接口中将接收到的前端请求参数XxxReqVo,我们想把这个入参转化为XxxQuery对象作为数据库的查询条件对象 传统做法是手动set,即 XxxBean xxxBea…

Python Opencv实践 - HoG特征计算

参考资料:https://www.cnblogs.com/alexme/p/11361563.html https://blog.csdn.net/qq_43348528/article/details/108638030 import cv2 as cv import numpy as np import matplotlib.pyplot as plt from skimage import exposure from skimage.feature i…

靶场溯源第二题

关卡描述:1. 网站后台登陆地址是多少?(相对路径) 首先这种确定的网站访问的都是http或者https协议,搜索http看看。关于http的就这两个信息,然后172.16.60.199出现最多,先过滤这个ip看看 这个很…

SSM - Springboot - MyBatis-Plus 全栈体系(八)

第二章 SpringFramework 四、SpringIoC 实践和应用 4. 基于 配置类 方式管理 Bean 4.4 实验三:高级特性:Bean 注解细节 4.4.1 Bean 生成 BeanName 问题 Bean 注解源码: public interface Bean {//前两个注解可以指定Bean的标识AliasFor…

Mendeley在linux中无法打开APPimage

原因:FUSE 库为用户空间程序提供了一个接口,可以将虚拟文件系统导出到 Linux 内核。由于缺少这个关键库,AppImage 无法按预期工作。 1 安装fuse,打开终端,输入命令 sudo apt install libfuse2 输入用户密码结,果如下 2 确保APPimage作为程序运行 右击…

docker 获取Nvidia 镜像 | cuda |cudnn

本文分享如何使用docker获取Nvidia 镜像,包括cuda10、cuda11等不同版本,cudnn7、cudnn8等,快速搭建深度学习环境。 1、来到docker hub官网,查看有那些Nvidia 镜像 https://hub.docker.com/r/nvidia/cuda/tags?page2&name11.…

【计算机视觉 | 图像模型】常见的计算机视觉 image model(CNNs Transformers) 的介绍合集(五)

文章目录 一、MoCo v3二、AmoebaNet三、Residual Multi-Layer Perceptrons四、FractalNet五、LV-ViT六、RepVGG七、Transformer in Transformer八、SimpleNet九、SpineNet十、Bottleneck Transformer十一、ZFNet十二、DetNet十三、Invertible Rescaling Network十四、SNet十五、…

SVN 索引版本与打包版本号不匹配

今天突然遇到了一个问题,SVN上传不了,错误提示如下: 解决方法: 1.其实,这是SVN库不小心搞坏了,只能重新再创建一个SVN仓库了。

Redis:分布式锁误删原因分析

一、线程阻塞 例如,线程一获取分布式锁,但是线程一阻塞时间过长,导致锁超时释放。此时线程二获取分布式锁。当线程一阻塞结束后,释放分布式锁,但是释放的却是线程二的锁。此时线程二就不安全了,线程三也可…

Linux下修改jar包中的配置文件application.conf

文件位置 jar包文件工程目录 打包后解压jar包目录 提取和上传 jar tf XXX.jar # 获取包内文件 application.conf是jar包的配置文件,如果修改需要 提取文件 jar xf my-app.jar application.conf 修改后上传文件 jar uf my-app.jar application.conf

解决开了burp suite ,火狐访问不了其他网站的问题

问题描述: 有软件正在阻止 Firefox 安全地连接至此网站 www.baidu.com 很像是一个安全(连接加密)的网站,但我们未能与它建立安全连接。这个问题是由 PortSwigger CA 所造成,它是您的计算机或您所在网络中的软件。 您…

为什么Proteus串口无法正常显示

我以前就可以正常显示,但是最近一段时间,发现串口无法正常显示,试了很多办法都不行, 然后今天干好有点时间就刷了个机,然后居然就好了, 这就说明:Proteus不正常可能是病毒破坏了某个文件导致异…

HSRP(热备份路由选择协议)的概念,原理与配置实验

作者:Insist-- 个人主页:insist--个人主页 梦想从未散场,传奇永不落幕,持续更新优质网络知识、Python知识、Linux知识以及各种小技巧,愿你我共同在CSDN进步 目录 一、了解HSRP协议 1. 什么是HSRP协议 2、HSRP协议的…

java和fastjson

1.java是如何跨平台通信的 java--->class字节码--->jvm虚拟机运行 2.使因为jvm只会读文件名 如果不一致 则无法找到文件 3.main 函数说明java代码的接口 被使用 4.java和class后缀的区别 java是当前编写的代码文件 class是编译后的文件 5.void 没有返回值 这…

Django系列:Django简介与MTV架构体系概述

Django系列 Django简介与MTV架构体系概述 作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 :291148484163.com 本文地址:https://blog.csdn.net/qq_28550263/article/details/132890054 【介…

Canny图像算法仿真

目录 一、简要说明 1.1 算法流程 第一步,图像降噪。 第二步,计算图像梯度,得到可能边缘。 第三步,非极大值抑制。 第四步,双阈值筛选。 1.2 验证流程: 二、操作步骤 第一步:获取图像 …

代码随想录算法训练营第48天|198. 打家劫舍,213. 打家劫舍 II,337. 打家劫舍 III

198. 打家劫舍 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个…