Set、Map有什么区别

SetMap 是 ES6 引入的两种新数据结构,它们在用途和特性上有明显区别:

1. 核心区别

特性 Set Map
存储内容 值的集合 键值对的集合
元素唯一性 值唯一 键唯一(值可以重复)
查找方式 直接通过值查找 通过键查找对应的值
默认迭代 返回 [value, value] 返回 [key, value]
典型用途 去重、成员检查 数据映射、字典、缓存

2. 详细对比

Set(集合)

js 复制代码
const set = new Set();
set.add(1);
set.add(2);
set.add(2); // 重复值不会被添加

console.log(set.size); // 2
console.log(set.has(1)); // true
set.forEach(value => console.log(value)); // 1, 2

// 去重示例
const arr = [1, 2, 2, 3, 3];
const unique = [...new Set(arr)]; // [1, 2, 3]

Map(映射)

js 复制代码
const map = new Map();
map.set('name', 'Alice');
map.set('age', 25);
map.set('age', 26); // 更新键'age'的值

console.log(map.size); // 2
console.log(map.get('name')); // 'Alice'
console.log(map.has('age')); // true

for (let [key, value] of map) {
  console.log(key, value); // 'name Alice', 'age 26'
}

3. 选择使用场景

使用 Set 的场景:

  • 数组去重
  • 检测元素是否存在于集合中
  • 数学中的集合运算(并集、交集、差集)
  • 存储唯一标识符列表

使用 Map 的场景:

  • 需要键值对存储,且键不是字符串
  • 需要维护键的插入顺序
  • 缓存数据(键值映射)
  • 需要频繁增删键值对
  • 对象作为键的情况

4. 共同特点

js 复制代码
// 1. 都维护插入顺序
const set = new Set();
set.add(1).add(3).add(2);
[...set]; // [1, 3, 2] - 保持插入顺序

const map = new Map();
map.set('a', 1).set('c', 3).set('b', 2);
[...map.keys()]; // ['a', 'c', 'b'] - 保持插入顺序

// 2. 性能相似
// 查找、添加、删除的时间复杂度都是 O(1)
// 都比 Object 更适合频繁增删的场景

// 3. 相同的迭代方法
// keys(), values(), entries(), forEach()

5. 与 Object 的对比

Map 优于 Object 的情况:

js 复制代码
// 1. 键可以是任意类型
const map = new Map();
const objKey = { id: 1 };
map.set(objKey, 'value'); // ✅ 允许对象作为键
map.set(NaN, 'number'); // ✅ 允许NaN作为键

// 2. 可以直接获取大小
map.size; // ✅ 直接获取
Object.keys(obj).length; // ❌ 需要计算

// 3. 迭代更友好
for (let [key, value] of map) { ... } // ✅

Set 优于 Array 的情况:

js 复制代码
// 1. 去重和查找性能更好
set.has(value); // O(1)
array.includes(value); // O(n)

// 2. 删除元素更高效
set.delete(value); // O(1)
array.splice(index, 1); // O(n)

6. 互相转换示例

js 复制代码
// Map ↔ Array
const map = new Map([['a', 1], ['b', 2]]);
const arr = [...map]; // [['a', 1], ['b', 2]]
const map2 = new Map(arr);

// Set ↔ Array
const set = new Set([1, 2, 3]);
const arr2 = [...set]; // [1, 2, 3]
const set2 = new Set(arr2);

// Map ↔ Object
const obj = Object.fromEntries(map); // {a: 1, b: 2}
const map3 = new Map(Object.entries(obj));

总结

  • Set值的集合,用于处理唯一值场景
  • Map键值对集合,用于建立映射关系
  • 两者都保持插入顺序,都有 O(1) 的查找性能
  • 选择依据:是否需要存储键值对关系,还是只需要存储独立的值
相关推荐
ETA81 小时前
不再是切图仔,router拯救了前端工程师
前端·react.js
毕设源码-朱学姐1 小时前
【开题答辩全过程】以 基于web网络投票系统平台的设计与实现为例,包含答辩的问题和答案
前端
萌狼蓝天1 小时前
[Vue]Tab关闭后,再次使用这个组件时,上次填写的内容依旧显示(路由复用导致组件实例未被销毁)
前端·javascript·vue.js·前端框架·ecmascript
皮坨解解1 小时前
关于领域模型的总结
前端
UIUV1 小时前
React+Zustand实战学习笔记:从基础状态管理到项目实战
前端·react.js·typescript
ETA81 小时前
理解 React 自定义 Hook:不只是“封装”,更是思维方式的转变
前端·react.js
岭子笑笑1 小时前
Vant4图片懒加载源码解析(二)
前端
千寻girling1 小时前
面试官 : “ 说一下 ES6 模块与 CommonJS 模块的差异 ? ”
前端·javascript·面试
贝格前端工场1 小时前
困在像素里:我的可视化大屏项目与前端价值觉醒
前端·three.js