Set 与 Map 深度解析:区别、特性与应用场景,弱引用版本对比:WeakSet 与 WeakMap

Set 与 Map 深度解析:区别、特性与应用场景

一、核心定义

数据类型 存储内容 键/值要求 重复性规则
Set 唯一值的集合 只有值(无键) 值不能重复
Map 键值对的集合 键值任意类型(包括对象引用) 键不能重复

简单对比

  • Set:类似数组,但值唯一 [1, 2, 3]
  • Map:类似对象,但键可以是对象 { [obj]: "data" }

二、关键特性对比

特性 Set Map
初始化方式 new Set([1, 2, 3]) new Map([[k1,v1], [k2,v2]])
元素唯一性判断 值严格相等(===,但 NaN=NaN 键严格相等(===,但 NaN=NaN
元素访问 无索引,只能遍历或查存在 通过键访问:map.get(key)
顺序性 插入顺序保留 插入顺序保留
常用方法 add(), delete(), has() set(), get(), has()
大小获取 set.size map.size

三、核心方法详解

Set 操作示例

arduino 复制代码
JavaScript
const set = new Set();
set.add("apple");          // 添加值
set.add("banana");
console.log(set.size);     // 2
console.log(set.has("apple")); // true
set.delete("banana");      // 删除
set.clear();               // 清空

Map 操作示例

c 复制代码
JavaScript
const map = new Map();
const keyObj = { id: 1 };

map.set(keyObj, "data");     // 键为对象
map.set(123, "数字键");      // 键为数字
console.log(map.get(keyObj)); // "data"
map.delete(123);             // 删除键

四、特殊行为

  1. 重复值处理

    • Set 添加重复值自动忽略:

      csharp 复制代码
      JavaScript
      const set = new Set();
      set.add(1).add(1); // 最终只有 1 个元素
    • Map 重复键会覆盖旧值:

      c 复制代码
      JavaScript
      map.set("key", "v1");
      map.set("key", "v2"); // 值变为 v2
  2. NaN 的特殊相等

    arduino 复制代码
    JavaScript
    const set = new Set();
    set.add(NaN).add(NaN); // 只保留 1 个 NaN
    
    const map = new Map();
    map.set(NaN, "test");
    console.log(map.get(NaN)); // "test"(NaN 可作为键)

五、与弱引用版本对比:WeakSet 与 WeakMap

特性 WeakSet WeakMap 与普通版本区别
键要求 只接受对象作为值 只接受对象作为键 ✅ 键/值必须是对象引用
可遍历性 ❌ 不可遍历 ❌ 不可遍历 ✅ 无 sizekeys() 等方法
垃圾回收 元素无引用时自动回收 键对象无引用时自动回收 ✅ 防止内存泄漏
应用场景 临时对象跟踪 对象关联元数据

典型场景

kotlin 复制代码
JavaScript
// WeakMap 存储私有数据
const privateData = new WeakMap();

class Person {
  constructor(name) {
    privateData.set(this, { name }); // this 作键
  }
  getName() {
    return privateData.get(this).name;
  }
}

六、应用场景指南

场景描述 推荐数据结构 原因
存储唯一值(如用户ID) Set 自动去重,高效判断存在性
需要保留插入顺序的键值对 Map 比普通对象更可靠的顺序保证
键需为非字符串(如对象/函数) Map 普通对象键会自动转字符串
临时缓存对象(防内存泄漏) WeakSet/WeakMap 自动回收无引用的对象
为对象关联私有数据 WeakMap 键为对象本身,对象销毁时数据自动清除
交集/并集运算(如好友关系) Set 通过 union(), intersection() 等方法实现高效集合运算

七、性能关键点

  1. 查找效率

    • Set.has(value)Map.has(key) 的时间复杂度为 O(1) (哈希表实现),远快于数组的 includes()(O(n))
  2. 与数组转换

    sql 复制代码
    JavaScript
    // Set → Array
    const arr = [...set]; 
    // Array → Set (去重)
    const set = new Set(arr);
  3. 遍历优化

    arduino 复制代码
    JavaScript
    // Set 遍历
    for (const value of set) { ... }
    // Map 遍历
    for (const [key, value] of map) { ... }

总结

  • Set:处理唯一值集合,替代数组去重,高效值存在性检查
  • Map:键值对存储的升级版,支持任意类型键,保留插入顺序
  • WeakSet/WeakMap:专为对象设计的弱引用容器,防止内存泄漏
  • 性能优先 :高频查找用 Set/Map,数组遍历改用 for...of 或传统 for

优先选择 Set/Map 的场景:

  1. 需要维护插入顺序
  2. 键为非字符串
  3. 高频存在性检查
  4. 避免内存泄漏(用 Weak 版本)
相关推荐
刘发财12 分钟前
前端2秒生成500页矢量PDF,rust真的强到没朋友
前端·javascript·rust
郑州光合科技余经理44 分钟前
国际版外卖系统:税率字段怎么和订单主流程解耦
android·java·开发语言·前端·后端·php·ai编程
梦想平凡1 小时前
百游棋牌源代码开发搭建教程(十):隔离部署、备份恢复与双端验收
java·前端·javascript·数据库·源代码管理
yume_sibai2 小时前
06-Rust Web 开发实战(Axum 框架 + 数据库 + JWT 认证 + 中间件 + 部署)
前端·数据库·rust
计算机魔术师4 小时前
特朗普上台打给黄仁勋:AI末日论是骗局,我们绝不让它发生
前端
troy1284 小时前
Python 基础语法(八):Web 后端开发、数据分析与可视化、网络爬虫、人工智能 / 大模型应用
前端·python·数据分析
计算机魔术师4 小时前
CEO说要慢下来,黑客说别做梦了——同一篇论文,两种命运
前端
kyriewen5 小时前
我花3天抓了一个幽灵bug,凶手藏在第4层
前端·javascript·程序员
IT_陈寒5 小时前
Java里用Stream.parallel()翻车实录,这性能还不如单线程
前端·人工智能·后端
wangchunyu1145 小时前
JavaScript 零基础入门教程
前端