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

ES6 Map 数据结构是用总结

1. Map 基本概念

Map 是 ES6 提供的新的数据结构,它类似于对象,但是"键"的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map 也可以跟踪键值对的原始插入顺序。

1.1 基本用法

// 创建一个空Map
const map = new Map();// 创建一个带有初始值的Map
const map1 = new Map([['name', 'John'],['age', 25]
]);// 使用对象作为键
const objKey = { id: 1 };
const map2 = new Map();
map2.set(objKey, 'value for object');// Map的大小
console.log(map1.size); // 2let myMap = new Map();
myMap.set("name", "Alice");
myMap.set(1, "one");
myMap.set(true, "boolean");
console.log(myMap); // Map { 'name' => 'Alice', 1 => 'one', true => 'boolean' }

1.2 Map的基本方法

const map = new Map();// 添加键值对
map.set('name', 'John');
map.set('age', 25).set('city', 'New York'); // 支持链式调用// 获取值
console.log(map.get('name')); // 'John'// 检查键是否存在
console.log(map.has('age')); // true// 删除键值对
map.delete('age');// 清空Map
map.clear();// 获取Map的大小
console.log(map.size); // 0
方法说明
set(key, value)添加键值对
get(key)获取键对应的值
delete(key)删除某个键值对
has(key)判断某个键是否存在
clear()清空 Map
size获取键值对数量
console.log(myMap.get("name")); // Alice
console.log(myMap.has(1)); // true
myMap.delete(true);
console.log(myMap.size); // 2
myMap.clear();
console.log(myMap.size); // 0

2. Map的遍历

2.1 遍历方法

const map = new Map([['name', 'John'],['age', 25],['city', 'New York']
]);// keys() - 返回键名的遍历器
for (let key of map.keys()) {console.log(key);
}// values() - 返回键值的遍历器
for (let value of map.values()) {console.log(value);
}// entries() - 返回键值对的遍历器
for (let [key, value] of map.entries()) {console.log(key, value);
}// forEach() - 使用回调函数遍历
map.forEach((value, key) => {console.log(key, value);
});let map = new Map([["name", "Alice"],["age", 25],["gender", "female"]
]);console.log([...map.keys()]); // ['name', 'age', 'gender']
console.log([...map.values()]); // ['Alice', 25, 'female']
console.log([...map.entries()]); // [['name', 'Alice'], ['age', 25], ['gender', 'female']]

2.2 与对象的转换

// Map转对象
function mapToObject(map) {const obj = {};for (let [key, value] of map) {obj[key] = value;}return obj;
}// 对象转Map
function objectToMap(obj) {return new Map(Object.entries(obj));
}// 使用示例
const map = new Map([['name', 'John'], ['age', 25]]);
const obj = mapToObject(map);
const backToMap = objectToMap(obj);

3. 实际应用场景

3.1 缓存系统

class Cache {constructor() {this.cache = new Map();}set(key, value, ttl = 60000) { // 默认缓存1分钟const expires = Date.now() + ttl;this.cache.set(key, { value, expires });}get(key) {const data = this.cache.get(key);if (!data) return null;if (Date.now() > data.expires) {this.cache.delete(key);return null;}return data.value;}clear() {this.cache.clear();}
}// 使用示例
const cache = new Cache();
cache.set('user', { id: 1, name: 'John' }, 5000); // 缓存5秒
console.log(cache.get('user')); // { id: 1, name: 'John' }

3.2 状态管理

class StateManager {constructor() {this.states = new Map();this.listeners = new Map();}setState(key, value) {this.states.set(key, value);if (this.listeners.has(key)) {this.listeners.get(key).forEach(listener => listener(value));}}getState(key) {return this.states.get(key);}subscribe(key, callback) {if (!this.listeners.has(key)) {this.listeners.set(key, new Set());}this.listeners.get(key).add(callback);}
}// 使用示例
const store = new StateManager();
store.subscribe('theme', theme => console.log(`Theme changed to ${theme}`));
store.setState('theme', 'dark'); // 输出: Theme changed to dark

3.3 事件总线

class EventBus {constructor() {this.events = new Map();}on(event, callback) {if (!this.events.has(event)) {this.events.set(event, new Set());}this.events.get(event).add(callback);}off(event, callback) {if (this.events.has(event)) {this.events.get(event).delete(callback);}}emit(event, data) {if (this.events.has(event)) {this.events.get(event).forEach(callback => callback(data));}}
}// 使用示例
const bus = new EventBus();
bus.on('userLogin', user => console.log(`${user.name} logged in`));
bus.emit('userLogin', { name: 'John' }); // 输出: John logged in

3.4 数据结构映射

class BiMap {constructor() {this.forward = new Map();this.reverse = new Map();}set(key, value) {this.forward.set(key, value);this.reverse.set(value, key);}getByKey(key) {return this.forward.get(key);}getByValue(value) {return this.reverse.get(value);}
}// 使用示例
const userRoles = new BiMap();
userRoles.set('john', 'admin');
console.log(userRoles.getByKey('john')); // 'admin'
console.log(userRoles.getByValue('admin')); // 'john'

4. WeakMap

WeakMap 是一种特殊的 Map,它只接受对象作为键,并且键是弱引用。

4.1 基本用法

const wm = new WeakMap();
let key = { id: 1 };
wm.set(key, 'value');console.log(wm.get(key)); // 'value'
key = null; // key对象可被垃圾回收

4.2 实际应用场景

// 使用 WeakMap 存储私有数据
const privateData = new WeakMap();class User {constructor(name, age) {privateData.set(this, { name, age });}getName() {return privateData.get(this).name;}getAge() {return privateData.get(this).age;}
}const user = new User('John', 25);
console.log(user.getName()); // 'John'

4.3 Map 与 WeakMap 的区别**

特性MapWeakMap
是否存储值✅ 是✅ 是
是否存储对象✅ 是✅ 仅能存对象
是否支持遍历✅ 是❌ 不能遍历
是否允许自动垃圾回收❌ 否✅ 是

📌 WeakMap 适用于 存储对象的私有数据,对象若被其他变量引用解除,会被自动回收,不会造成内存泄漏。

let weakMap = new WeakMap();
let obj = { name: "John" };
weakMap.set(obj, "privateData");
console.log(weakMap.get(obj)); // privateData
obj = null; // 当对象无引用时会被垃圾回收

5. 性能考虑

5.1 Map vs Object

特性MapObject
键的类型任意类型仅字符串或 Symbol
是否有默认原型❌ 否✅ 是(Object.prototype
遍历顺序按插入顺序无序(ES6 之后部分实现有序)
适合场景需要键值存储,键可为任意类型传统键值对、JSON 结构
// Map 在频繁增删键值对时性能更好
const map = new Map();
const obj = {};console.time('Map');
for (let i = 0; i < 1000000; i++) {map.set(i, i);map.delete(i);
}
console.timeEnd('Map');console.time('Object');
for (let i = 0; i < 1000000; i++) {obj[i] = i;delete obj[i];
}
console.timeEnd('Object');let obj = {};
obj["1"] = "one";
obj[1] = "number one";
console.log(obj); // { '1': 'number one' }  因为 Object 的键被转换为字符串let map = new Map();
map.set("1", "one");
map.set(1, "number one");
console.log(map); // Map { '1' => 'one', 1 => 'number one' }

5.2 内存优化

// 及时清理不需要的数据
function processData(data) {const map = new Map();// 处理数据...map.clear(); // 及时清空释放内存
}

6. 最佳实践

  1. 需要非字符串键时使用 Map
  2. 需要保持键值对顺序时使用 Map
  3. 频繁增删键值对时使用 Map
  4. 存储私有数据时考虑使用 WeakMap
  5. 需要遍历键值对时使用 Map
  6. 注意内存管理,及时清理不需要的数据

相关文章:

ES6 Map 数据结构是用总结

1. Map 基本概念 Map 是 ES6 提供的新的数据结构&#xff0c;它类似于对象&#xff0c;但是"键"的范围不限于字符串&#xff0c;各种类型的值&#xff08;包括对象&#xff09;都可以当作键。Map 也可以跟踪键值对的原始插入顺序。 1.1 基本用法 // 创建一个空Map…...

go结构体详解

结构体简介 Golang 中没有“类”的概念&#xff0c;Golang 中的结构体和其他语言中的类有点相似。和其他面向对象语言中的类相比&#xff0c;Golang 中的结构体具有更高的扩展性和灵活性。 Golang 中的基础数据类型可以表示一些事物的基本属性&#xff0c;但是当我们想表达一…...

机器学习-关于线性回归的表示方式和矩阵的基本运算规则

最近在学习机器学习的过程中&#xff0c;发现关于线性回归的表示和矩阵的运算容易费解&#xff0c;而且随着学习的深入容易搞混&#xff0c;因此特意做了一些研究&#xff0c;并且记录下来和大家分享。 一、线性模型有哪些表示方式&#xff1f; 器学习中&#xff0c;线性模型…...

kafka 3.5.0 raft协议安装

前言 最近做项目&#xff0c;需要使用kafka进行通信&#xff0c;且只能使用kafka&#xff0c;笔者没有测试集群&#xff0c;就自己搭建了kafka集群&#xff0c;实际上笔者在很早之前就搭建了&#xff0c;因为当时还是zookeeper&#xff08;简称ZK&#xff09;注册元数据&#…...

后台管理系统网页开发

CSS样式代码 /* 后台管理系统样式文件 */ #container{ width:100%; height:100%; /* background-color:antiquewhite;*/ display:flex;} /* 左侧导航区域:宽度300px*/ .left{ width:300px; height: 100%; background-color:#203453; display:flex; flex-direction:column; jus…...

使用一个大语言模型对另一个大语言模型进行“调教”

使用一个大语言模型对另一个大语言模型进行“调教”&#xff08;通常称为微调或适配&#xff09;&#xff0c;是一种常见的技术手段&#xff0c;用于让目标模型更好地适应特定的任务、领域或风格。以下是基于搜索结果整理的详细步骤和方法&#xff1a; 1.准备工作 安装必要的…...

golang使用sqlite3,开启wal模式,并发读写

因为sqlite是基于文件的&#xff0c;所以默认情况下&#xff0c;sqlite是不支持并发读写的&#xff0c;即写操作会阻塞其他操作&#xff0c;同时sqlite也很容易就产生死锁。 但是作为一个使用广泛的离线数据库&#xff0c;从sqlite3.7.0版本开始&#xff08;SQLite Release 3.…...

如何利用maven更优雅的打包

最近在客户现场部署项目&#xff0c;有两套环境&#xff0c;无法连接互联网&#xff0c;两套环境之间也是完全隔离&#xff0c;于是问题就来了&#xff0c;每次都要远程到公司电脑改完代码&#xff0c;打包&#xff0c;通过网盘&#xff08;如果没有会员&#xff0c;上传下载慢…...

音频进阶学习十二——Z变换一(Z变换、收敛域、性质与定理)

文章目录 前言一、Z变换1.Z变换的作用2.Z变换公式3.Z的状态表示1&#xff09; r 1 r1 r12&#xff09; 0 < r < 1 0<r<1 0<r<13&#xff09; r > 1 r>1 r>1 4.关于Z的解释 二、收敛域1.收敛域的定义2.收敛域的表示方式3.ROC的分析1&#xff09;当 …...

cursor指令工具

Cursor 工具使用指南与实例 工具概览 Cursor 提供了一系列强大的工具来帮助开发者提高工作效率。本指南将通过具体实例来展示这些工具的使用方法。 1. 目录文件操作 1.1 查看目录内容 (list_dir) 使用 list_dir 命令可以查看指定目录下的文件结构: 示例: list_dir log…...

MySQL 主从读写分离实现方案(一)—MariaDB MaxScale实现mysql8读写分离

一&#xff1a;MaxScale 是干什么的&#xff1f;? MaxScale是maridb开发的一个mysql数据中间件&#xff0c;其配置简单&#xff0c;能够实现读写分离&#xff0c;并且可以根据主从状态实现写库的自动切换&#xff0c;对多个从服务器能实现负载均衡。 二&#xff1a;MaxScale …...

阿里云 | DeepSeek人工智能大模型安装部署

ModelScope是阿里云人工智能大模型开源社区 ModelScope网络链接地址 https://www.modelscope.cn DeepSeek模型库网络链接地址 https://www.modelscope.cn/organization/deepseek-ai 如上所示&#xff0c;在阿里云人工智能大模型开源社区ModelScope中&#xff0c;使用阿里云…...

LLAMA-Factory安装教程(解决报错cannot allocate memory in static TLS block的问题)

步骤一&#xff1a; 下载基础镜像 # 配置docker DNS vi /etc/docker/daemon.json # daemon.json文件中 { "insecure-registries": ["https://swr.cn-east-317.qdrgznjszx.com"], "registry-mirrors": ["https://docker.mirrors.ustc.edu.c…...

STM32 CUBE Can调试

STM32 CUBE Can调试 1、CAN配置2、时钟配置3、手动添加4、回调函数5、启动函数和发送函数6、使用方法(采用消息队列来做缓存)7、数据不多在发送函数中获取空邮箱发送&#xff0c;否则循环等待空邮箱 1、CAN配置 2、时钟配置 3、手动添加 需要注意的是STM32CUBE配置的代码需要再…...

MySQL数据存储- 索引组织表

索引组织表 前言数据存储堆表索引组织表 二级索引二级索引的性能评估&#x1f539;为什么 idx_name 的性能开销最大&#xff1f;&#x1f539; 为什么 idx_last_modify_date 更新频繁会影响性能&#xff1f;分析二级索引性能表格为什么主键应该“紧凑且顺序”&#xff1f;二级索…...

基于STM32设计的仓库环境监测与预警系统

目录 项目开发背景设计实现的功能项目硬件模块组成设计思路系统功能总结使用的模块的技术详情介绍总结 1. 项目开发背景 随着工业化和现代化的进程&#xff0c;尤其是在制造业、食品业、医药业等行业&#xff0c;仓库环境的监控和管理成为了至关重要的一环。尤其是在存储易腐…...

VSCode便捷开发

一、常用插件 Vue 3 Snippets、Vetur、Vue - Official 二、常用开发者工具 三、Vue中使用Element-UI 安装步骤&#xff1a; 1、在VSCode的终端执行如下指令&#xff1a; npm i element-ui -S 2、在main.js中全局引入&#xff1a; import Vue from vue; import ElementUI from …...

理解 Maven 的 pom.xml 文件

pom.xml 是 Maven 项目的核心文件&#xff0c;它是项目构建、依赖管理、插件配置和项目元数据的主要地方。通过 pom.xml 文件&#xff0c;Maven 知道如何构建项目、下载依赖库、执行测试等任务。每个 Maven 项目都必须包含一个 pom.xml 文件。本文将详细讲解 pom.xml 文件的结构…...

docker数据持久化的意义

Docker 数据持久化是指在 Docker 容器中保存的数据不会因为容器的停止、删除或重启而丢失。Docker 容器本身是临时性的&#xff0c;默认情况下&#xff0c;容器内的文件系统是临时的&#xff0c;容器停止或删除后&#xff0c;其中的数据也会随之丢失。为了确保重要数据&#xf…...

opentelemetry-collector 配置elasticsearch

一、修改otelcol-config.yaml receivers:otlp:protocols:grpc:endpoint: 0.0.0.0:4317http:endpoint: 0.0.0.0:4318 exporters:debug:verbosity: detailedotlp/jaeger: # Jaeger supports OTLP directlyendpoint: 192.168.31.161:4317tls:insecure: trueotlphttp/prometheus: …...

ASP.NET Core JWT Version

目录 JWT缺点 方案 实现 Program.cs IdentityHelper.cs Controller NotCheckJWTVersionAttribute.cs JWTVersionCheckkFilter.cs 优化 JWT缺点 到期前&#xff0c;令牌无法被提前撤回。什么情况下需要撤回&#xff1f;用户被删除了、禁用了&#xff1b;令牌被盗用了&…...

【ArcGIS】R语言空间分析、模拟预测与可视化技术

R语言在空间数据挖掘中具有广泛的应用&#xff0c;以下是一些关键内容和常用包的介绍&#xff1a; R语言空间数据挖掘的关键技术 空间数据类型 矢量数据&#xff1a;包括点&#xff08;Point&#xff09;、线&#xff08;Line&#xff09;、面&#xff08;Polygon&#xff09;等…...

日常知识点之面试后反思遗留问题汇总

梳理一下最近接触到的几个知识点&#xff1a; 1&#xff1a;突然问到端口复用 &#xff08;SO_REUSEADDR&#xff09; 端口复用一般用在服务端重启时&#xff0c;套接字处于time_wait状态时&#xff0c;无法绑定该端口&#xff0c;导致无法启动问题。 设置端口复用&#xff…...

链表(LinkedList) 1

上期内容我们讲述了顺序表&#xff0c;知道了顺序表的底层是一段连续的空间进行存储(数组)&#xff0c;在插入元素或者删除元素需要将顺序表中的元素整体移动&#xff0c;时间复杂度是O(n)&#xff0c;效率比较低。因此&#xff0c;在Java的集合结构中又引入了链表来解决这一问…...

Qt:Qt Creator项目创建

目录 认识Qt Creator Qt Creator概览 使用Qt Creator新建项目 选择项目模板 选择项目路径 选择构建系统 填写类信息设置界面 选择语言和翻译文件 选择Qt套件 选择版本控制系统 最终效果 认识Qt Creator Qt Creator概览 从开始菜单或者快捷方式打开Qt Creator集成开…...

windows11上,使用pipx安装Poetry,Poetry的安装路径是什么?

当使用 pipx 安装 Poetry 时&#xff0c;pipx 会将 Poetry 安装到一个独立的虚拟环境中&#xff0c;并将其可执行文件链接到一个集中的目录中。以下是 pipx 安装 Poetry 时的路径信息&#xff1a; 1. Poetry 的安装路径 pipx 会为每个工具&#xff08;如 Poetry&#xff09;创…...

详解状态模式

引言 水有固态、液态、气态三种状态&#xff0c;在不同条件下这三种状态可以相互转化。同样在软件设计中&#xff0c;有些对象也有不同的状态&#xff0c;不同状态的行为不同&#xff0c;状态模式就是用来处理这种情况的。 1.概念 状态模式(State Pattern)&#xff1a;允许一个…...

能否通过蓝牙建立TCP/IP连接来传输数据

前言&#xff1a; 最近在做一个项目时&#xff0c;产生了一个疑问&#xff1a;能否通过蓝牙建立TCP/IP连接来传输数据 查阅了一些文章&#xff0c;可以得出结论&#xff1a;不行 下面是我截取的两篇个人认可的文章的回答&#xff1a; 文章一&#xff1a; 蓝牙是一种短距离无…...

uniapp mqttjs 小程序开发

在UniApp中集成MQTT.js开发微信小程序时&#xff0c;需注意平台差异、协议兼容性及消息处理等问题。以下是关键步骤与注意事项的综合指南&#xff1a; 一、环境配置与依赖安装 安装MQTT.js 推荐使用兼容性较好的版本&#xff1a;mqtt4.1.0&#xff08;H5和小程序兼容性最佳&…...

爬虫工程师分享:获取京东商品详情SKU数据的技术难点与攻破方法

在电商数据领域&#xff0c;京东商品详情页的SKU数据是许多爬虫工程师的目标。这些数据包含了商品的价格、库存、规格等关键信息&#xff0c;对于市场分析、价格监控等应用场景至关重要。然而&#xff0c;获取这些数据并非易事&#xff0c;京东作为国内电商巨头&#xff0c;其反…...