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 版本)
相关推荐
小小小小宇2 小时前
虚拟列表兼容老DOM操作
前端
悦悦子a啊2 小时前
Python之--基本知识
开发语言·前端·python
安全系统学习3 小时前
系统安全之大模型案例分析
前端·安全·web安全·网络安全·xss
涛哥码咖4 小时前
chrome安装AXURE插件后无效
前端·chrome·axure
OEC小胖胖4 小时前
告别 undefined is not a function:TypeScript 前端开发优势与实践指南
前端·javascript·typescript·web
行云&流水4 小时前
Vue3 Lifecycle Hooks
前端·javascript·vue.js
Sally璐璐4 小时前
零基础学HTML和CSS:网页设计入门
前端·css
老虎06274 小时前
JavaWeb(苍穹外卖)--学习笔记04(前端:HTML,CSS,JavaScript)
前端·javascript·css·笔记·学习·html
灿灿121385 小时前
CSS 文字浮雕效果:巧用 text-shadow 实现 3D 立体文字
前端·css
烛阴5 小时前
Babel 完全上手指南:从零开始解锁现代 JavaScript 开发的超能力!
前端·javascript