ES6 Map 数据结构是用总结

news2025/2/10 16:05:53

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); // 2

let 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. 注意内存管理,及时清理不需要的数据

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用wpa_supplicant和wpa_cli 扫描wifi热点及配网

一&#xff1a;简要说明 交叉编译wpa_supplicant工具后会有wpa_supplicant和wpa_cli两个程序生产&#xff0c;如果知道需要连接的wifi热点及密码的话不需要遍历及查询所有wifi热点的名字及信号强度等信息的话&#xff0c;使用wpa_supplicant即可&#xff0c;否则还需要使用wpa_…

大模型应用与实战:专栏概要与内容目录

文章目录 大模型应用与实战&#x1f4da; 核心内容模块一、大模型推理与部署1.1 推理框架应用实践1.2 框架源码深度解析1.3 高并发部署优化1.4 国产化平台适配 二、Agent框架专题2.1 Langchain系列2.2 Qwen-Agent系列2.3 Dify应用实践2.4 框架对比与迁移 三、微调技术研究3.1 微…

Arbess基础教程-创建流水线

Arbess(谐音阿尔卑斯) 是一款开源免费的 CI/CD 工具&#xff0c;本文将介绍如何使用 Arbess 配置你的第一条流水线&#xff0c;以快速入门上手。 1. 创建流水线 根据不同需求来创建不同的流水线。 1.1 配置基本信息 配置流水线的基本信息&#xff0c;如分组&#xff0c;环境&…

科普书《从一到无穷大》的科普知识推翻百年集论

科普书《从一到无穷大》的科普知识推翻百年集论 黄小宁 “我们给两组无穷大数列中的各个数一一配对&#xff0c;如果最后这两组都一个不剩&#xff0c;这两组无穷大就是相等的&#xff1b;如果有一组还有些数没有配出去&#xff0c;这一组就比另一组大些&#xff0c;或者说强些…

【键盘识别】实例分割

第一步 键盘检测 方案一 canny边缘检测 canny边缘检测检测结果不稳定,容易因为复杂背景或光线变换检测出其他目标。 如图是用canny边缘检测方法标出的检测出的边缘的四个红点。 参考的是这篇文章OpenCV实战之三 | 基于OpenCV实现图像校正_opencv 图像校正-CSDN博客 方案二…

25/2/7 <机器人基础>雅可比矩阵计算 雅可比伪逆

雅可比矩阵计算 雅可比矩阵的定义 假设我们有一个简单的两个关节的平面机器人臂&#xff0c;其末端执行器的位置可以表示为&#xff1a; 其中&#xff1a; L1​ 和 L2 是机器人臂的长度。θ1​ 和 θ2是关节的角度。 计算雅可比矩阵 雅可比矩阵 JJ 的定义是将关节速度与末…

apisix的real-ip插件使用说明

k8s集群入口一般都需要过负载均衡&#xff0c;然后再到apisix。 这时候如果后台业务需要获取客户端ip&#xff0c;可能拿到的是lb或者网关的内网ip。 这里一般要获取真实ip需要做几个处理。 1. 负载均衡上&#xff0c;一般支持配置获取真实ip参数&#xff0c;需要配置上。然…

Python实现GO鹅优化算法优化支持向量机SVM分类模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后关注获取。 1.项目背景 随着信息技术的迅猛发展&#xff0c;数据量呈爆炸式增长&#xff0c;如何从海量的数据中提取有价值…

我用AI做数据分析之数据清洗

我用AI做数据分析之数据清洗 AI与数据分析的融合效果怎样&#xff1f; 这里描述自己在使用AI进行数据分析&#xff08;数据清洗&#xff09;过程中的几个小故事&#xff1a; 1. 变量名的翻译 有一个项目是某医生自己收集的数据&#xff0c;变量名使用的是中文&#xff0c;分…

备战蓝桥杯:双指针(滑动窗口)算法之逛花展

P1638 逛画展 - 洛谷 | 计算机科学教育新生态 这道题我们只要用一个kind和一个mp[N]的数组就能解决了 我们的解法1就是暴力枚举&#xff0c;先固定2&#xff0c;从2开始找连续的满足所有种类的最短的子数组&#xff0c;然后固定5&#xff0c;3&#xff0c;1&#xff0c;3&…

collabora online+nextcloud+mariadb在线文档协助

1、环境 龙蜥os 8.9 docker 2、安装docker dnf -y install dnf-plugins-core dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sed -i shttps://download.docker.comhttps://mirrors.tuna.tsinghua.edu.cn/docker-ce /etc/yum.repos.…

深度学习中的Checkpoint是什么?

诸神缄默不语-个人CSDN博文目录 文章目录 引言1. 什么是Checkpoint&#xff1f;2. 为什么需要Checkpoint&#xff1f;3. 如何使用Checkpoint&#xff1f;3.1 TensorFlow 中的 Checkpoint3.2 PyTorch 中的 Checkpoint3.3 transformers中的Checkpoint 4. 在 NLP 任务中的应用5. 总…

用深度学习模型构建海洋动物图像分类保姆教程

使用深度学习模型构建深度学习海洋动物图像分类模型的完整步骤如下&#xff0c;分为关键阶段和详细操作说明&#xff1a; 1. 数据准备与预处理 1.1 数据集组织 按类别分文件夹存储图像&#xff0c;例如&#xff1a;dataset/train/class1/class2/...val/class1/class2/...test…

npm无法加载文件 因为此系统禁止运行脚本

安装nodejs后遇到问题&#xff1a; 在项目里【node -v】可以打印出来&#xff0c;【npm -v】打印不出来&#xff0c;显示npm无法加载文件 因为此系统禁止运行脚本。 但是在winr&#xff0c;cmd里【node -v】,【npm -v】都也可打印出来。 解决方法&#xff1a; cmd里可以打印出…

知识库升级新思路:用生成式AI打造智能知识助手

在当今信息爆炸的时代&#xff0c;企业和组织面临着海量数据的处理和管理挑战。知识库管理系统&#xff08;Knowledge Base Management System, KBMS&#xff09;作为一种有效的信息管理工具&#xff0c;帮助企业存储、组织和检索知识。然而&#xff0c;传统的知识库系统往往依…

蚂蚁爬行最短问题

初二数学问题记录 分析过程 考点&#xff1a;2点之间直线最短。 思考过程&#xff1a;将EBCF以BC为边翻折&#xff0c;EF边翻折后为&#xff0c;则A为蚂蚁需要爬行的最小距离。

【电机控制器】STC8H1K芯片——低功耗

【电机控制器】STC8H1K芯片——低功耗 文章目录 [TOC](文章目录) 前言一、芯片手册说明二、IDLE模式三、PD模式四、PD模式唤醒五、实验验证1.接线2.视频&#xff08;待填&#xff09; 六、参考资料总结 前言 使用工具&#xff1a; 1.STC仿真器烧录器 提示&#xff1a;以下是本…

【专题】2024-2025人工智能代理深度剖析:GenAI 前沿、LangChain 现状及演进影响与发展趋势报告汇总PDF洞察(附原数据表)

原文链接&#xff1a;https://tecdat.cn/?p39630 在科技飞速发展的当下&#xff0c;人工智能代理正经历着深刻的变革&#xff0c;其能力演变已然成为重塑各行业格局的关键力量。从早期简单的规则执行&#xff0c;到如今复杂的自主决策与多智能体协作&#xff0c;人工智能代理…

SAP-ABAP:SAP的第一行REPORT后面后缀作用详解

在SAP ABAP中&#xff0c;REPORT 语句是定义报表程序的核心语句&#xff0c;其后可以跟多个后缀&#xff08;参数&#xff09;&#xff0c;用于控制报表的行为和属性。以下是常见的 REPORT 后缀及其作用的详解&#xff1a; 程序名称 • 语法&#xff1a;REPORT <program_nam…

25/2/8 <机器人基础> 阻抗控制

1. 什么是阻抗控制&#xff1f; 阻抗控制旨在通过调节机器人与环境的相互作用&#xff0c;控制其动态行为。阻抗可以理解为一个力和位移之间的关系&#xff0c;涉及力、速度和位置的协同控制。 2. 阻抗控制的基本概念 力控制&#xff1a;根据感测的外力调节机械手的动作。位置…