当前位置: 首页 > news >正文

一文读懂 JS 中的 Map 结构

你好,我是沐爸,欢迎点赞、收藏、评论和关注。

上次聊了 Set 数据结构,今天我们聊下 Map,看看它与 Set、与普通对象有什么区别?下面直接进入正题。

一、Set 和 Map 有什么区别?

  • Set 是一个集合,类似于数组,但是成员的值都是唯一的,不能重复。主要用于快速查找、去重等场景。
  • Map 是一组键值对的集合,其中每个元素都是一个键值对。与普通的对象不同,Map 的键不仅限于字符串,也可以是任意类型(如对象或函数)。

二、WeakMap 和 Map 的区别?

WeakMap 结构与 Map 结构类似,也是用于生成键值对的集合。两者的区别在于:

  • WeakMap 只接受对象(null除外)和 Symbol 值作为键名,不接受其他类型的值作为键名。
  • WeakMap 对象不计入垃圾回收机制。
  • Map 可遍历,WeakMap 不可遍历。

三、Map 实例有哪些属性和方法?

1.属性

  • size:返回 Map 实例的成员总数

2.方法

  • 操作方法
    • set(key, value) 添加键值,返回 Map 实例本身
    • get(key) 获取key对应的键值,获取不到返回undefined
    • has(key) 查询该键存在于 Map 对象中,返回一个布尔值
    • delete(key) 删除某个键值对,成功返回true,失败返回false
    • clear() 清除所有成员,没有返回值
  • 遍历方法:
    • keys() 返回键名的遍历器
    • values() 返回键值的遍历器
    • entries() 返回键值对的遍历器
    • forEach() 使用回调函数遍历每个成员
// 示例1
const m = new Map();
const o = {p: 'Hello World'};m.set(o, 'content')
m.get(o) // "content"
m.has(o) // true
m.delete(o) // true
m.has(o) // false
m.set(o, 'content')
m.clear()// 示例2
const map = new Map().set(1, 'a').set(2, 'b');for (let item of map.keys()) console.log(item)
// 1
// 2for (let item of map.values()) console.log(item)
// 'a'
// 'b'map.forEach(item => console.log(item))
// 'a'
// 'b'for (let item of map.entries()) console.log(item)
// [1, 'a']
// [2, 'b']

set 方法重复给相同的 key(键)设置值,新值会覆盖旧值。

let map = new Map()
map.set(1, 'a')
map.set(1, 'b')
// Map(1) {1 => 'b'}

set 方法返回的是当前的 Map 对象,因此可以采用链式写法。

const map = new Map().set(1, 'a').set(2, 'b').set(3, 'c');

任何具有 Iterator 接口、且每个成员都是一个双元素的数组的数据结构都可以当作 Map 构造函数的参数。

// 示例1:数组参数
const map = new Map([['name', '张三'],['title', 'Author']
]);// 示例2:Set参数
const set = new Set([[1, 'a'],[2, 'b']
])
const map = new Map(set)
map // Map(2) {1 => 'a', 2 => 'b'}// 示例3:Map参数
const m1 = new Map([[1, 'a']]);
m1 // {1 => 'a'}
const m2 - new Map(m1)
m2 // {1 => 'a'}

Map 具有 iterator 接口,可直接用 for…of 循环遍历。

const map = new Map().set(1, 'a').set(2, 'b');for (let item of map) console.log(item)
// [1, 'a']
// [2, 'b']

只有对同一个对象的引用,Map 结构才将其视为同一个键。这一点要非常小心。

const map = new Map();map.set(['a'], 1);
map.get(['a']) // undefinedlet b = ['b']
map.set(b, 2)
map.get(b) // 2

Map 将两个 NaN 视为相等,将 -0和+0视为相等。

const map = new Map();map.set(-0, 'a')
map.set(+0, 'b')
map.set(NaN, 'c')
map.set(NaN, 'd')map // Map(2) {0 => 'b', NaN => 'd'}

四、Map与数组、对象的相互转换

1.Map 转数组

const map = new Map().set(1, 'a').set(2, 'b');
[...map]  // [[1, 'a'], [2, 'b']]

2.Map 转对象

const map = new Map().set(1, 'a').set(2, 'b');function mapToObj(map) {let obj = {}for (let [key, value] of map) {obj[key] = value}return obj
}mapToObj(map) // {1: 'a', 2: 'b'}

3.数组转 Map

const arr = [[1, 'a'],[2, 'b']
]
const map = new Map(arr)
map // Map(2) {1 => 'a', 2 => 'b'}

4.对象转 Map

const obj = {1: 'a', 2: 'b'}
const map = new Map(Object.entries(obj))
map // Map(2) {'1' => 'a', '2' => 'b'}

五、Map 的使用场景有哪些?

  • 快速查找:当你需要存储键值对,并希望根据键快速检索值时,Map是理想选择。
  • 非字符串键:对象通常只能使用字符串作为键,而 Map 允许使用任何类型的值(包括对象、数组、函数等)作为键。
  • 有序集合:Map 保持键值对的插入顺序,这在需要按照特定顺序处理元素时很有用。
  • 数据缓存:Map 的 delete 和 clear 方法提供了管理缓存数据的便利方式,有助于避免内存泄漏。

六、WeakMap 如何使用?

  • WeakMap 只接受对象(null除外)和 Symbol 值作为键名,不接受其他类型的值作为键名
  • 有4个方法:get、set、has,delete,用法同 Map
  • 没有 size 属性和 clear 方法,不支持遍历,for/forEach/keys()/values()/entries()都不能用
const wm = new WeakMap();wm.set(1, 2) // 报错
wm.set(null, 2) // 报错
wm.set(Symbol(), 2) // 不报错
wm.set({}, 2) // 不报错// size、forEach、clear 方法都不存在
wm.size // undefined
wm.forEach // undefined
wm.clear // undefined

七、WeakMap 的使用场景?

  • 对象关联数据:将特定数据关联到对象上,而不用担心这些数据影响对象的垃圾回收。
  • 缓存:作为缓存结构,自动处理无用对象的内存回收,避免内存泄漏。
  • 私有数据存储:提供一种方式存储对象的私有数据,外部无法直接访问。
  • 解决循环引用:在复杂的对象图中,帮助处理循环引用导致的内存回收问题。

关联阅读:一文读懂 JS 中的 Set 结构


好了,分享结束,谢谢点赞,下期再见。

相关文章:

一文读懂 JS 中的 Map 结构

你好,我是沐爸,欢迎点赞、收藏、评论和关注。 上次聊了 Set 数据结构,今天我们聊下 Map,看看它与 Set、与普通对象有什么区别?下面直接进入正题。 一、Set 和 Map 有什么区别? Set 是一个集合&#xff0…...

C++校招面经(二)

欢迎关注 0voice GitHub 6、 C 和 Java 区别(语⾔特性,垃圾回收,应⽤场景等) 指针: Java 语⾔让程序员没法找到指针来直接访问内存,没有指针的概念,并有内存的⾃动管理功能,从⽽…...

Python Web 面试题

1 Web 相关 get 和 post 区别 get: 请求数据在 URL 末尾,URL 长度有限制 请求幂等,即无论请求多少次,服务器响应始终相同,这是因为 get 至少获取资源,而不修改资源 可以被浏览器缓存,以便以后…...

java日志框架之JUL(Logging)

文章目录 一、JUL简介1、JUL组件介绍 二、Logger快速入门三、Logger日志级别1、日志级别2、默认级别info3、原理分析4、自定义日志级别5、日志持久化(保存到磁盘) 三、Logger父子关系四、Logger配置文件 一、JUL简介 JUL全程Java Util Logging&#xff…...

ARM驱动学习之PWM

ARM驱动学习之PWM 1.分析原理图: GPD0_0 XpwmTOUT0定时器0 2.定时器上的资源: 1.5组32位定时器 2.定时器产生内部中断 3.定时器0,1,2可编程实现pwm 4.定时器各自分频 5.TCN--,TCN TCMPBN 6.分频器 24-2 7.24.3.4 例子&#xff1…...

我的AI工具箱Tauri版-VideoClipMixingCut视频批量混剪

本教程基于自研的AI工具箱Tauri版进行VideoClipMixingCut视频批量混剪。 VideoClipMixingCut视频批量混剪 是自研AI工具箱Tauri版中的一款强大工具,专为自动化视频批量混剪设计。该模块通过将预设的解说文稿与视频素材进行自动拼接生成混剪视频,适合需要…...

postgres_fdw访问存储在外部 PostgreSQL 服务器中的数据

文章目录 一、postgres_fdw 介绍二、安装使用示例三、成本估算四、 远程执行选项执行计划无法递推解决 参考文件: 一、postgres_fdw 介绍 postgres_fdw 模块提供外部数据包装器 postgres_fdw,可用于访问存储在外部 PostgreSQL 服务器中的数据。 此模块…...

什么是3D展厅?有何优势?怎么制作3D展厅?

一、什么是3D展厅? 3D展厅是一种利用三维技术构建的虚拟展示空间。它借助虚拟现实(VR)、增强现实(AR)等现代科技手段,将真实的展示空间数字化,呈现出逼真、立体、沉浸的展示效果。通过3D展厅&a…...

Linux下的CAN通讯

CAN总线 CAN总线简介 CAN&#xff08;Controller Area Network&#xff09;总线是一种多主从式 <font color red>异步半双工串行 </font> 通信总线&#xff0c;它最早由Bosch公司开发&#xff0c;用于汽车电子系统。CAN总线具有以下特点&#xff1a; 多主从式&a…...

【Python】pip安装加速:使用国内镜像源

【Python】pip安装加速&#xff1a;使用国内镜像源 零、使用命令行设置 设置全局镜像源 随便使用下面任一命令即可&#xff01; 阿里云&#xff1a; pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/豆瓣&#xff1a; pip config set global.in…...

SpringBoot lombok(注解@Getter @Setter)

SpringBoot lombok(注解Getter Setter) 使用lombok注解的方式&#xff0c;在编译生成的字节码文件中就会存在setter/getter等方法&#xff0c;减少代码量&#xff0c;方便了代码的维护 添加依赖 <dependency><groupId>org.projectlombok</groupId><artif…...

descrTable常用方法

descrTable 为 R 包 compareGroups 的重要函数&#xff0c;有关该函数以及 compareGroups 包的详细内容见&#xff1a;R包compareGroups详细用法 加载包和数据 library(compareGroups)# 加载 REGICOR 数据&#xff08;横断面&#xff0c;从不同年份纳入&#xff0c;每个变量有…...

回归预测 | Matlab实现ReliefF-XGBoost多变量回归预测

回归预测 | Matlab实现ReliefF-XGBoost多变量回归预测 目录 回归预测 | Matlab实现ReliefF-XGBoost多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.ReliefF-xgboost回归预测代码&#xff0c;对序列数据预测性能相对较高。首先通过ReleifF对输入特征计算权…...

年度最强悬疑美剧重磅回归,一集比一集上头

纽约的夜晚&#xff0c;平静被一声枪响打破&#xff0c;一场离奇的谋杀案悄然上演。《大楼里只有谋杀》正是围绕这样一桩扑朔迷离的案件展开的。三位主角&#xff0c;赛琳娜戈麦斯饰演的梅宝、史蒂夫马丁饰演的查尔斯、马丁肖特饰演的奥利弗&#xff0c;这些性格迥异的邻居因为…...

AI一点通: 简化大数据与深度学习工作流程, Apache Spark、PyTorch 和 Mosaic Streaming

在大数据和机器学习飞速发展的领域中&#xff0c;数据科学家和机器学习工程师经常面临的一个挑战是如何桥接像 Apache Spark 这样的强大数据处理引擎与 PyTorch 等深度学习框架。由于它们在架构上的固有差异&#xff0c;利用这两个系统的优势可能令人望而生畏。本博客介绍了 Mo…...

Python知识点:深入理解Python的模块与包管理

开篇&#xff0c;先说一个好消息&#xff0c;截止到2025年1月1日前&#xff0c;翻到文末找到我&#xff0c;赠送定制版的开题报告和任务书&#xff0c;先到先得&#xff01;过期不候&#xff01; 深入理解Python的模块与包管理 Python的模块和包是代码组织、复用和分发的基本…...

倒排索引(反向索引)

倒排索引&#xff08;Inverted Index&#xff09;是搜索引擎和数据库管理系统中常用的一种数据结构&#xff0c;用于快速检索文档集合中的文档。在全文搜索场景中&#xff0c;倒排索引是一种非常高效的手段&#xff0c;因为它能够快速定位到包含特定关键词的所有文档。 1、基本…...

openCV的python频率域滤波

在OpenCV中实现频率域滤波通常涉及到傅里叶变换(Fourier Transform)和其逆变换(Inverse Fourier Transform)。傅里叶变换是一种将图像从空间域转换到频率域的数学工具,这使得我们可以更容易地在图像的频域内进行操作,如高通滤波、低通滤波等。 下面,我将提供一个使用Py…...

探索视频美颜SDK与直播美颜工具的开发实践方案

直播平台的不断发展&#xff0c;让开发出性能优异、效果自然的美颜技术&#xff0c;成为了技术团队必须面对的重要挑战。本篇文章&#xff0c;小编将深入讲解视频美颜SDK与直播美颜工具的开发实践方案。 一、视频美颜SDK的核心功能 视频美颜SDK是视频处理中的核心组件&#xf…...

Linux通过yum安装Docker

目录 一、安装环境 1.1. 旧的docker包卸载 1.2. 安装常规环境包 1.3. 设置存储库 二、安装Docker社区版 三、解决拉取镜像失败 3.1. 创建文件目录/etc/docker 3.2. 写入镜像配置 https://docs.docker.com/engine/install/centos/ 检测操作系统版本&#xff0c;我操作的…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言&#xff1a; 通过AI视觉技术&#xff0c;为船厂提供全面的安全监控解决方案&#xff0c;涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面&#xff0c;能够实现对应负责人反馈机制&#xff0c;并最终实现数据的统计报表。提升船厂…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

CMake 从 GitHub 下载第三方库并使用

有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...