javascript数组去重需据数据类型选择策略:原始值用set(支持nan、保序);对象数组需json.stringify或深度比较;混合类型应分层处理,兼顾可读性与健壮性。

掌握 JavaScript 数组去重的高级进阶技巧,关键不在堆砌方法,而在于理解“重复”的定义如何随数据类型变化,并据此选择匹配的工具和策略。原始值、对象、混合类型、含 NaN 或特殊结构(如嵌套数组)的数组,各自有最适合的解法。下面分三类讲清核心要点和实操建议。
原始值去重:优先用 Set,但注意 NaN 和类型区分
数字、字符串、布尔值、undefined、null、Symbol 这些原始值,Set 是首选,一行代码搞定:[...new Set(arr)] 或 Array.from(new Set(arr))。它时间复杂度 O(n),保序,语义清晰。
需要留意两个细节:
-
NaN 能被正确识别为重复项:因为
Set内部使用的是 SameValueZero 算法,NaN === NaN为 true;而indexOf基于严格相等(===),会把 NaN 当作不等于自身,导致去重失败。 - 1 和 "1" 不算重复:这是合理行为,体现 JS 类型安全。若业务要求“数值等价去重”,需先统一转类型(如全转 Number),再进 Set。
对象数组去重:不能靠引用,得靠内容比对
对象是引用类型,{a:1} 和 {a:1} 是两个不同对象,Set 或 indexOf 都无法识别它们内容相同。这时必须把“判断是否重复”的逻辑显式写出来。
最常用且可靠的方式是 JSON.stringify + Set 哈希表:
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
- 对每个对象调用
JSON.stringify(obj)得到唯一字符串标识; - 用一个 Set 记录已见过的字符串;
- 只保留那些字符串未出现过的对象。
注意局限:函数、undefined、Symbol、循环引用无法被 JSON 序列化,会导致丢失或报错。生产环境建议配合 lodash.isEqual 或手写深度比较函数替代 stringify。
混合类型与边界场景:按需组合,避免黑盒依赖
当数组里既有数字、字符串,又有对象甚至 NaN、null、undefined,单一方法容易翻车。例如 Set 能处理 NaN,但对对象无效;filter + indexOf 对 NaN 失效,且性能差(O(n²))。
推荐采用分层策略:
- 先用
Array.isArray()和typeof判断元素类型; - 原始值走 Set;
- 对象走基于 key 的去重(如按
id字段)或深度比较; - 对 null/undefined 单独处理(它们在 Set 中能被正确保留一份)。
不要为了“一行代码”牺牲可读性和健壮性。真正高级的技巧,是写出能自解释、易测试、覆盖边界 case 的函数,而不是炫技式的单行表达式。










