Set 和 Map 是 ES6 新增的两种集合类型,它们的设计目标和使用场景不同,同时也常与其他数据结构(如对象、数组、WeakSet、WeakMap)进行比较

43 阅读3分钟

一、Set 与 Map 的核心区别

维度SetMap
存储内容存储单个值(value)  的集合存储键值对(key-value)  的集合
唯一性依据集合中的值(value)  唯一,重复值会被忽略集合中的键(key)  唯一,相同键会覆盖旧值
核心用途用于存储不重复的元素(如去重、检查元素是否存在)用于键值映射(如存储键对应的关联信息)
键的特性可看作 “键和值相同” 的特殊集合(forEach 回调中 key 与 value 一致)键可以是任意类型(原始值、对象等),且严格区分引用(如两个不同对象即使内容相同也视为不同键)
迭代方式迭代器返回单个值(如 for...of 循环直接取 value)迭代器返回 **[key, value] 数组 **(如 for...of 循环需解构)
常用方法add(value)has(value)delete(value)set(key, value)has(key)delete(key)get(key)

二、通常还会与哪些数据结构比较?

1. 与 对象(Object)  比较(主要针对 Map

Map 和对象都是 “键值对” 存储结构,但核心差异如下:

  • 键的类型:对象的键只能是 字符串或 Symbol(非字符串键会被自动转为字符串,如 obj[{}] 实际键是 "[object Object]");Map 的键可以是任意类型(原始值、对象、函数等),且保留引用唯一性。
  • 原型链干扰:对象会继承原型链上的属性(如 obj.hasOwnProperty 可能冲突);Map 无原型链,仅包含自身存储的键值对。
  • 长度获取:对象需通过 Object.keys(obj).length 计算长度;Map 直接通过 size 属性获取。
  • 迭代便捷性:对象需先通过 Object.keys()/values()/entries() 转换为数组才能迭代;Map 本身是可迭代对象,支持 for...of 直接遍历。

2. 与 数组(Array)  比较(主要针对 Set

Set 和数组都是 “值的集合”,但差异如下:

  • 唯一性Set 自动去重(重复值会被忽略);数组允许重复元素。
  • 查找效率Set 的 has(value) 方法时间复杂度为 O(1) (哈希表实现);数组的 includes(value)/indexOf(value) 时间复杂度为 O(n) (需遍历)。
  • 访问方式Set 无索引,不能通过下标访问元素;数组通过索引(arr[0])访问,支持有序操作(如 slicesplice)。
  • 适用场景Set 适合去重、快速判断元素是否存在;数组适合需要有序访问、索引操作或重复元素的场景。

3. 与 WeakSetWeakMap 比较

WeakSet 和 WeakMap 是 “弱引用” 版本的集合,与 Set/Map 的核心差异是内存管理

  • 引用类型WeakSet 只能存储对象(不能存原始值),WeakMap 的键必须是对象(值可以是任意类型);Set/Map 可存储任意类型。
  • 弱引用特性WeakSet/WeakMap 对对象的引用是 “弱引用”—— 若对象没有其他强引用,会被垃圾回收机制回收,同时自动从集合中删除;Set/Map 对对象是 “强引用”,会阻止垃圾回收。
  • 功能限制WeakSet/WeakMap 没有 size 属性,不支持迭代(for...of),也没有 clear() 方法;Set/Map 支持这些功能。
  • 适用场景WeakSet/WeakMap 适合临时存储对象相关信息(如避免内存泄漏);Set/Map 适合需要长期存储、迭代或统计数量的场景。

总结

  • Set 是 “去重的值集合”,Map 是 “键唯一的键值对集合”,核心差异在存储内容和用途。
  • 常与对象(键值对对比)、数组(值集合对比)、WeakSet/WeakMap(内存管理对比)进行比较,选择时需根据是否需要去重、键类型、迭代需求、内存管理等场景判断。