Set和Map是JavaScript中ES6新增的两种数据结构,主要区别如下:
1. 存储内容
-
Set
存储唯一值的集合,所有元素都是值(无键值对)。
例:new Set([1, 2, 3])存储值1、2、3。 -
Map
存储键值对(Key-Value)的集合,键可以是任意类型(对象、函数等)。
例:new Map([['name', 'Alice'], [{ id: 1 }, 'data']])。
2. 主要用途
-
Set
- 去重(自动过滤重复值)。
- 快速检查某个值是否存在(比数组高效)。
- 集合运算(交集、并集等)。
-
Map
- 存储关联数据,键值对映射。
- 替代普通对象(Object),支持非字符串/Symbol类型的键。
- 保留键的插入顺序(普通对象不保证顺序)。
3. API对比
| 操作 | Set | Map |
|---|---|---|
| 添加元素 | add(value) | set(key, value) |
| 获取元素 | 无(需遍历或检查存在性) | get(key) |
| 删除元素 | delete(value) | delete(key) |
| 检查存在性 | has(value) | has(key) |
| 元素数量 | size | size |
| 清空 | clear() | clear() |
4. 初始化方式
-
Set
接受数组或可迭代对象,元素作为值:const set = new Set([1, 2, 3]); -
Map
接受二维数组或可迭代对象,子数组为[key, value]:const map = new Map([['name', 'Alice'], [42, 'answer']]);
5. 遍历方式
-
Set
直接遍历值:set.forEach(value => { /* ... */ }); // 或 for (const value of set) { /* ... */ } -
Map
遍历键值对(默认迭代器为entries()):map.forEach((value, key) => { /* ... */ }); // 或 for (const [key, value] of map) { /* ... */ }也可单独遍历键或值:
map.keys(); // 所有键 map.values(); // 所有值
6. 应用场景
-
Set
- 数组去重:
[...new Set(array)] - 记录访问过的对象,避免重复处理。
- 数组去重:
-
Map
- 缓存数据(键为请求参数,值为结果)。
- 关联对象与附加信息(如用DOM节点作为键存储元数据)。
- 需要保留插入顺序的键值对集合。
总结
| 特性 | Set | Map |
|---|---|---|
| 存储内容 | 唯一值 | 键值对 |
| 键类型 | 无键(仅值) | 任意类型 |
| 元素唯一性依据 | 值本身 | 键 |
| 典型用途 | 去重、集合运算 | 键值映射、保留插入顺序 |