news 2026/1/30 18:01:43

JavaScript中的Set和Map

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JavaScript中的Set和Map

一、前言:为什么需要 Set 和 Map?

在 JavaScript 中,数组(Array)和对象(Object)是最常用的数据结构,但它们在特定场景下存在明显短板:

  • 数组查找元素需遍历,时间复杂度 O (n),且去重需额外处理;
  • 对象的键只能是字符串 /.Symbol,无法直接使用引用类型作为键,且无法快速获取键值对数量。

ES6 引入的Set(集合)和Map(映射),正是为解决这些痛点而生 —— 它们提供了更高效的查找、插入、删除操作,以及更灵活的键类型支持,成为复杂业务场景的优选数据结构。

二、Set:不重复元素的有序集合

2.1 核心特性
  • 元素唯一:自动去重,重复添加的元素会被忽略;
  • 有序存储:按插入顺序保存元素(ES6 规范),遍历顺序与插入顺序一致;
  • 支持多种类型:可存储字符串、数字、布尔值、引用类型(对象、数组等);
  • 无键名只有值:本质是 “值 - 值” 映射,可理解为 “只有键的数组”。
2.2 常用 API(含示例)

// 1. 初始化

const set = new Set([1, 2, 2, 'a', true]); // 自动去重:Set(4) {1, 2, 'a', true}

// 2. 增删改查

set.add(3); // 添加元素:Set(5) {1, 2, 'a', true, 3}

set.delete('a'); // 删除元素:返回true(成功)/false(失败)

set.has(2); // 查找元素:返回true

set.size; // 获取长度:4

set.clear(); // 清空集合:Set(0) {}

// 3. 遍历方式

const set2 = new Set(['x', 'y', 'z']);

// 方式1:for...of遍历

for (const val of set2) {

console.log(val); // x, y, z

}

// 方式2:forEach遍历

set2.forEach((val, index) => {

console.log(val); // x, y, z(index与val相同)

});

// 方式3:转换为数组

const arr = [...set2]; // ['x', 'y', 'z']

2.3 实战场景
  1. 数组去重:const uniqueArr = [...new Set(arr)];(简洁高效,时间复杂度 O (n));
  1. 数据筛选:存储不重复的 ID、标签等,如const userIds = new Set(['101', '102', '101']);;
  1. 快速判断存在性:比数组indexOf更高效(Set 查找为 O (1),数组为 O (n))。

三、Map:键值对的灵活映射

3.1 核心特性
  • 键类型无限制:可使用字符串、数字、对象、数组、Symbol 等作为键;
  • 有序存储:按插入顺序保存键值对,遍历顺序与插入顺序一致;
  • 键唯一:重复设置同一键会覆盖旧值;
  • 可迭代:支持直接遍历,无需像对象那样先获取键数组。
3.2 常用 API(含示例)

// 1. 初始化

const map = new Map([

['name', '张三'],

[18, '年龄'],

[{ id: 1 }, '用户信息'] // 对象作为键

]);

// 2. 增删改查

map.set('gender', '男'); // 添加键值对:Map(4) {['name','张三'], [18,'年龄'], [{id:1},'用户信息'], ['gender','男']}

map.get(18); // 获取值:'年龄'

map.has('name'); // 查找键:true

map.delete({ id: 1 }); // 注意:对象键是引用类型,需用同一引用才能删除

map.size; // 获取长度:3

map.clear(); // 清空映射

// 3. 遍历方式

const map2 = new Map([['a', 1], ['b', 2]]);

// 方式1:遍历键值对(最常用)

for (const [key, val] of map2) {

console.log(key, val); // a 1, b 2

}

// 方式2:遍历键/值

for (const key of map2.keys()) { /* 遍历键 */ }

for (const val of map2.values()) { /* 遍历值 */ }

// 方式3:forEach遍历

map2.forEach((val, key) => {

console.log(key, val); // a 1, b 2

});

3.3 关键注意点
  • 引用类型作为键:对象、数组等引用类型作为键时,只有引用完全一致才视为同一键:

const obj1 = { id: 1 };

const obj2 = { id: 1 };

const map = new Map([[obj1, 'test']]);

map.get(obj2); // undefined(obj1与obj2是不同引用)

  • 与对象的区别

特性

Map

Object

键类型

任意类型

字符串 / Symbol

遍历顺序

插入顺序

无序(ES6 前)

长度获取

size 属性直接获取

需手动计算(Object.keys (obj).length)

迭代性

直接迭代

需先获取键数组

四、Set 与 Map 的核心区别与选型建议

4.1 核心区别

维度

Set

Map

存储结构

单值集合(值 - 值)

键值对映射(键 - 值)

核心用途

存储不重复元素

键值对关联查询

常用操作

去重、判断存在性

键值映射、数据关联

遍历返回值

直接返回元素

返回 [key, value] 数组

4.2 选型建议
  • 若需存储不重复的数据(如 ID、标签、去重数组),优先用Set;
  • 若需键值对映射(如配置表、缓存数据、字典),优先用Map;
  • 若键是引用类型(如对象),只能用Map;
  • 若只需简单的字符串键映射,且无需有序性,可考虑普通对象(但 Map 更灵活)。

五、性能优化与注意事项

  1. 性能对比
    • 插入 / 删除 / 查找操作:Set > Map > 数组 > 普通对象(数据量越大,优势越明显);
    • 遍历速度:Map > Set > 数组 > 普通对象(Map/Set 直接迭代,无需额外处理)。
  1. 注意事项
    • Set的forEach回调中,index 参数与 value 相同(设计特性,无需纠结);
    • Map的键是引用类型时,需保存同一引用才能修改 / 删除(避免隐式错误);
    • 避免用for...in遍历 Map/Set(不支持,需用for...of或forEach);
    • 序列化问题:JSON.stringify无法直接序列化 Map/Set,需手动转换为数组:

// Map序列化

const map = new Map([['a', 1]]);

const json = JSON.stringify([...map]); // "[[\"a\",1]]"

// Set序列化

const set = new Set([1, 2]);

const json = JSON.stringify([...set]); // "[1,2]"

六、总结

Set 和 Map 作为 ES6 的核心数据结构,解决了数组和普通对象的诸多痛点:Set 提供高效的不重复集合管理,Map 提供灵活的键值对映射。掌握它们的特性、API 和适用场景,能让你的代码更简洁、高效、易维护 —— 在数据去重、缓存管理、字典映射等场景中,它们往往是比数组和对象更优的选择。

建议在实际开发中多尝试用 Set/Map 替代传统数据结构,感受其带来的开发效率提升~

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/29 14:00:25

52、Red Hat Enterprise Linux系统管理与维护指南

Red Hat Enterprise Linux系统管理与维护指南 1. 关键知识点概述 在Red Hat Enterprise Linux系统中,有多个重要的方面需要我们关注,下面为大家详细介绍。 1.1 服务与特殊用户 当Red Hat Enterprise Linux启动时,会触发一个名为 init 的特殊进程,该进程会开启Linux系…

作者头像 李华
网站建设 2026/1/29 12:47:13

【2026毕设选题推荐】Hadoop饮食数据分析系统源码,Python+Spark技术栈详解 毕业设计 选题推荐 毕设选题 数据分析 机器学习

✍✍计算机编程指导师 ⭐⭐个人介绍:自己非常喜欢研究技术问题!专业做Java、Python、小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目:有源码或者技术上的问题欢迎在评论区一起讨论交流! ⚡⚡如果你遇到具体的…

作者头像 李华
网站建设 2026/1/29 13:21:34

Data Formulator:重新定义AI驱动数据可视化的智能探索工具

Data Formulator:重新定义AI驱动数据可视化的智能探索工具 【免费下载链接】data-formulator 🪄 Create rich visualizations with AI 项目地址: https://gitcode.com/GitHub_Trending/da/data-formulator 在当今数据驱动的商业环境中&#xff0…

作者头像 李华
网站建设 2026/1/29 11:54:24

20、网络安全与用户管理全解析

网络安全与用户管理全解析 一、用户配置文件与登录脚本 在Windows系统中,用户配置文件是一项非常实用的功能。它能记录单个用户对Windows配置的偏好设置。对于非联网计算机而言,用户配置文件使得两个或更多用户可以使用同一台计算机,并且各自拥有独立的桌面设置,像壁纸、…

作者头像 李华
网站建设 2026/1/29 13:25:34

QuickJS多线程编程完全指南:从入门到精通

QuickJS多线程编程完全指南:从入门到精通 【免费下载链接】quickjs Public repository of the QuickJS Javascript Engine. Pull requests are not accepted. Use the mailing list to submit patches. 项目地址: https://gitcode.com/gh_mirrors/qu/quickjs …

作者头像 李华
网站建设 2026/1/28 17:57:33

代码随想录 200.岛屿数量

思路:(1)题目中每座岛屿只能由水平方向和竖直方向上相邻的陆地连接而成,也就是说斜角度的连接不算。例如示例二,是三个岛屿。(2)本题的思路是遇到一个没有遍历过的节点陆地,计数器就…

作者头像 李华