javascript原生set/map仅按引用比较对象,无法深层去重;需用json.stringify或稳定序列化生成唯一key,配合map实现深比较集合,并注意nan相等性、键序敏感及性能优化。

JavaScript 中的 Set 或 Map 等集合默认使用 SameValueZero(类似 ===)比较对象,即只比引用,不比内容。所以两个结构完全相同的对象,只要不是同一个引用,就会被当作不同元素存入集合。要实现“深层比较”的集合行为,不能直接依赖原生 Set,需手动封装逻辑。
用 Map 模拟支持深比较的集合
核心思路:把对象序列化为唯一字符串键(如 JSON 字符串),再用 Map 存储。这样相同结构的对象会映射到同一 key,达到“内容去重”效果。
- 适合纯数据对象(无函数、undefined、Date、RegExp、循环引用等)——可用
JSON.stringify(obj)作 key - 对含特殊值的对象,需先用安全的序列化函数(如
fast-json-stable-stringify或自定义 deepEqual + 缓存 key) - 注意:JSON 会忽略 undefined、function、Symbol,且 Date 变成字符串,若需保留类型,应改用结构化克隆或自定义序列化规则
封装一个 DeepSet 类
继承 Set 接口风格,内部用 Map + 自定义 hash 函数管理唯一性:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 添加时:先计算对象的稳定哈希(如基于字段排序后的 JSON 字符串),查 Map 是否已存在该 hash;不存在则存入,并记录原始对象(或仅存 hash)
- 删除/检查时:同样用 hash 查找,避免遍历全部元素
- 可选支持自定义比较器(如传入 (a, b) => boolean 的 compareFn),在 hash 冲突时做 fallback 比较
用 WeakMap 缓存比较结果提升性能
当需频繁判断两个对象是否“深层相等”(比如在 add 前校验),直接递归比较开销大。可用 WeakMap 记录已比较过的对象对:
- 以
obj1为 key,value 是另一个 WeakMap:innerMap.get(obj2)返回布尔值 - 利用 WeakMap 不阻止 GC 的特性,避免内存泄漏
- 仅适用于临时高频比较场景,不替代持久化集合逻辑
注意事项与边界情况
深层比较永远绕不开语义歧义问题:
- 数组和对象字面量顺序敏感(
{a:1,b:2}≠{b:2,a:1}),但某些业务希望忽略键序 —— 需预处理键名排序 - NaN === NaN 为 false,但深层比较中通常认为 NaN 相等,需单独处理
- 原型链、getter/setter、不可枚举属性是否参与比较,需按需约定
- 性能敏感场景慎用深比较,建议结合业务做分层设计(例如先用 id 字段快速判等,再按需深比)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










