JavaScript 中 WeakMap、WeakSet、Set、Map、Object、Array 的区别与应用场景

在 JavaScript 中,数据结构的选择直接影响代码的性能、可读性与维护性。本文将深入比较 WeakMap、WeakSet、Set、Map、Object 和 Array 六种常用数据结构的特点、区别及典型应用场景。


一、Array:有序列表

特点

  • 按索引(数字)访问元素,适合顺序存储。
  • 支持常用操作如:push、pop、shift、unshift、splice。
  • 可以存储任意类型元素(包括对象)。

应用场景

  • 需要顺序处理的数据集合。
  • 需要频繁遍历、排序、筛选的列表。
  • 小规模查找(不频繁用索引查找对象)。

示例

js 复制代码
const list = [1, 2, 3];
list.push(4); // [1,2,3,4]

二、Object:键值对结构(键为字符串或 Symbol)

特点

  • 传统的键值对容器,键只能是字符串或 Symbol。
  • 原型链可能引发属性冲突(可使用 Object.create(null) 解决)。
  • 无法直接遍历,需借助 Object.keys()、Object.entries()。

应用场景

  • 用作配置对象(key 为已知的字符串标识)。
  • 不需频繁添加删除项。
  • 键值对较固定时更适合。

示例

js 复制代码
const config = {
  baseUrl: "https://api.example.com",
  timeout: 3000
};

三、Set:值的集合(无重复)

特点

  • 只存储值,不存储键,值唯一。
  • 自动去重。
  • 可遍历(支持 forEach、for...of)。
  • 元素可为任意类型。

应用场景

  • 数组去重。
  • 检查某个值是否存在(比数组更高效)。
  • 需要频繁添加/删除元素且不重复。

示例

js 复制代码
const ids = new Set([1, 2, 2, 3]);
console.log(ids); // Set(3) {1, 2, 3}

四、Map:键值对结构(键可为任意类型)

特点

  • 键可以是对象、函数、任意类型。
  • 有序:按照插入顺序保存。
  • 遍历友好(支持 forEach、entries())。
  • 大数据量下比 Object 更高效。

应用场景

  • 需要以对象为键时。
  • 有大量键值对操作(增删查改)时。
  • 保持键值对插入顺序。

示例

js 复制代码
const map = new Map();
const objKey = {};
map.set(objKey, "value");
console.log(map.get(objKey)); // "value"

五、WeakMap:弱引用键值对(键只能是对象)

特点

  • 键必须是对象,对键的引用是弱引用。
  • 不可枚举(无 forEach、keys 等方法)。
  • 键对象被垃圾回收时,WeakMap 自动释放对应的值。
  • 无法清空或遍历所有项。

应用场景

  • 对象私有属性的存储(封装、隐藏数据)。
  • DOM 节点绑定数据,不影响垃圾回收。
  • 缓存场景中临时关联对象数据。

示例

js 复制代码
const wm = new WeakMap();
let el = document.querySelector("#myDiv");
wm.set(el, { clicked: true });
// 当 el 被移除并为 null 后,wm 中对应数据也会被清除

六、WeakSet:弱引用集合(值必须是对象)

特点

  • 值必须是对象,并且是唯一的。
  • 弱引用存储,不能遍历。
  • 没有 size 属性,不支持清空。
  • 自动垃圾回收机制。

应用场景

  • 跟踪对象是否存在某个状态(如"是否访问过"、"是否处理过")。
  • 对象集合存储,但无需手动清理。
  • 防止内存泄漏。

示例

js 复制代码
const ws = new WeakSet();
let user = { name: "Alice" };
ws.add(user);
// 自动释放,当 user 不再引用

七、对比总结

特性 Array Object Set Map WeakSet WeakMap
键类型 数字索引 字符串/Symbol 值 任意 对象 对象
值类型 任意 任意 任意 任意 对象 任意
是否可迭代 ✅ ❌ (需转化) ✅ ✅ ❌ ❌
键值对支持 ❌ ✅ ❌ ✅ ❌ ✅
自动去重 ❌ ❌ ✅ ❌ ✅ ❌
键是弱引用 ❌ ❌ ❌ ❌ ✅ ✅
GC 自动清除 ❌ ❌ ❌ ❌ ✅ ✅
典型用途 列表、顺序 配置对象、JSON 去重、集合 映射表 跟踪对象状态 私有数据存储

八、使用建议

  • ✅ 用 Array 做列表,配合 filter、map、reduce 操作。
  • ✅ 用 Object 存储结构化数据,key 是固定字符串时最合适。
  • ✅ 用 Set 做去重、快速判断值是否存在。
  • ✅ 用 Map 替代复杂 Object,尤其当键可能为对象时。
  • ✅ 用 WeakMap 隐藏对象的元数据,或者做私有变量封装。
  • ✅ 用 WeakSet 标记对象是否已访问、避免内存泄漏。
相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万3 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋3 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁3 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王95273 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大3 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师3 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学3 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端