ES6 中的 Map
和 Set
是两种新的数据结构,虽然它们都可以用于存储集合类型的数据,但它们在存储方式和功能上有显著的区别。下面我们将从几个方面来比较 Map
和 Set
的区别。
1. 数据结构与存储方式
Map:存储的是键值对,即
key-value
形式的数据,键和值都可以是任意类型(如对象、函数等)。- 每一个键(
key
)都是唯一的。 - 可以用对象、字符串、数字、函数等作为键。
- 每一个键(
Set:存储的是唯一值的集合,每个值只能出现一次,且值不能重复。
Set
只存储值,不需要键,因此不像Map
那样需要成对存储数据。- 值的类型也可以是任意的(如对象、函数等)。
2. 使用场景
Map:适用于需要键值对存储的场景,如哈希表、字典。你可以通过键来快速查找对应的值。
示例:
let map = new Map();
map.set('name', 'Alice');
map.set('age', 25);
console.log(map.get('name')); // 'Alice'
console.log(map.get('age')); // 25
Set:适用于存储唯一值的场景,类似于数学中的集合,特别适合去重操作或管理一组唯一对象。
示例:
let set = new Set(); set.add(1); set.add(5); set.add(5); // 重复的值不会被加入 console.log(set.has(5)); // true console.log(set.size); // 2
3. API 方法
Map 的常用方法:
set(key, value)
:向Map
中添加一个键值对。get(key)
:根据键返回对应的值。has(key)
:判断Map
中是否包含某个键。delete(key)
:删除指定键的元素。clear()
:清空Map
。size
:返回Map
中的键值对数量。keys()
:返回一个包含所有键的迭代器。values()
:返回一个包含所有值的迭代器。entries()
:返回所有键值对的迭代器([key, value]
形式)。
Set 的常用方法:
add(value)
:向Set
中添加一个值。has(value)
:判断Set
中是否包含某个值。delete(value)
:删除某个值。clear()
:清空Set
。size
:返回Set
中的值的数量。values()
:返回一个包含所有值的迭代器(Set
的值就是键值,所以values()
和keys()
是相同的)。entries()
:返回所有值的迭代器(每个值作为[value, value]
的形式,符合Map
的[key, value]
形式)。
4. 键与值的区别
Map:
Map
的键和值可以是任意数据类型,包括对象。示例:
let map = new Map(); map.set({}, 'objectValue'); console.log(map.get({})); // undefined,因为 {} 是不同的对象
Set:
Set
中只存储值,且值必须是唯一的,值和引用地址的判断是基于SameValueZero
算法(类似于===
,但NaN
被认为等同于NaN
)。示例:
let set = new Set(); set.add({}); set.add({}); // 这是另一个对象,允许加入 console.log(set.size); // 2
5. 遍历方式
Map:可以使用
forEach()
遍历键值对,也可以使用for...of
循环遍历Map
对象。Map
的遍历顺序是按照插入顺序。示例:
let map = new Map([['name', 'Alice'], ['age', 25]]); map.forEach((value, key) => { console.log(key, value); });
Set:可以使用
forEach()
遍历值,或者使用for...of
循环遍历。Set
的遍历顺序也是插入顺序。示例:
let set = new Set([1, 2, 3]); set.forEach(value => { console.log(value); });
6. 重复项处理
Map:
Map
中同一个键只能存储一个值,如果插入相同的键,新的值会覆盖旧的值。示例:
let map = new Map(); map.set('key', 'value1'); map.set('key', 'value2'); // 后者覆盖前者 console.log(map.get('key')); // 'value2'
Set:
Set
不允许有重复值,添加相同的值不会导致Set
中的元素增加。示例:
let set = new Set([1, 2, 3]); set.add(3); // 不会添加,因为 Set 中已有 3 console.log(set.size); // 3
7. 性能比较
Map 和 Set 都具有较快的查找、插入和删除操作的时间复杂度(通常为 O(1)),适合需要频繁操作键值对或集合的场景。
Map
提供了高效的键值对查找能力。Set
提供了高效的集合操作,适合需要快速判断值是否存在的场景。
总结
特性 Map Set 数据结构 键值对( key-value
)唯一值( value
)主要用途 存储键值对数据 存储唯一值 键的类型 可以是任意类型 不适用 值的类型 可以是任意类型 也可以是任意类型 重复键/值 允许键覆盖 不允许重复值 常用方法 set()
,get()
,has()
,delete()
add()
,has()
,delete()
遍历方式 forEach()
,for...of
forEach()
,for...of
应用场景 字典、哈希表 去重、集合操作 Map
适用于需要通过键值对存储和访问数据的场景,而Set
则适合存储不重复值的集合操作,比如数组去重、集合运算等。