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

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 替代传统数据结构,感受其带来的开发效率提升~

http://www.cnnetsun.cn/news/37612.html

相关文章:

  • MediaPipe Hands终极指南:手部追踪技术完整解析
  • 25岁,转行网络安全工程师来还来得及吗?手把手带你入门到精通
  • 如何3步快速上手鲁班H5表单数据收集系统:从小白到高手的完整指南
  • 完整掌握DNVGL-ST-0126风机支撑结构:权威资源快速获取指南
  • 15、线程取消机制的深入解析与应用
  • 20、POSIX 线程编程中的关键函数与机制解析
  • 如何快速提升API文档质量:5个自动化检查工具对比
  • 道路缺陷检测-道路病害-YOLO模型-毕业设计
  • 9、深入解析 SQL 注入漏洞:原理、案例与防范
  • GOCAD三维地质建模
  • 2025 年网络安全学习路线:从零基础到实战大神,避开 90% 的坑(非常详细,附工具包以及学习资源包)
  • Reachability隐私合规完全指南:iOS 17+一键配置解决方案
  • 初等数论终极指南:密码学必备的5个核心数学原理
  • 中文论文格式模板使用指南
  • 视觉AI提示词设计:从困惑到精通的实战指南
  • wangEditor导入微信公众号内容自动排版CMS
  • 5个步骤:Open GApps完整安装指南,快速定制你的Android系统
  • 软件测试(2):白盒测试
  • ComfyUI与Auto1111 WebUI对比:谁更适合你的项目?
  • 终极指南:VQ-Diffusion高效图像生成模型完全解析
  • 8、音频与视频的奇妙玩法
  • 从新手到技术专家:软件开发知识的系统化学习路径
  • 4、树莓派音频使用全攻略
  • 初解神经网络优化算法
  • Linux shell 进阶教程:单引号会禁止变量展开
  • 如何让AI工作流真正理解你的业务场景?
  • 如何快速安装Sionna:面向新手的完整配置教程
  • SketchUp STL插件实战手册:从建模到3D打印的完整流程
  • 零基础玩转AI音乐风格识别:Magenta实战指南
  • 零基础玩转智能配色:Color Thief色彩提取实战指南