Set、Map有什么区别

7 阅读2分钟

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

1. 核心区别

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

2. 详细对比

Set(集合)

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(映射)

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. 共同特点

// 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 的情况:

// 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 的情况:

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

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

6. 互相转换示例

// 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) 的查找性能
  • 选择依据:是否需要存储键值对关系,还是只需要存储独立的值