结论:数组去重必须先明确去重对象类型——基础类型用 Set(支持 NaN、O(n)、简洁高效),对象数组需按字段用 Map 或 JSON.stringify(Set 无效),混合类型要警惕 undefined/函数/Symbol 的序列化丢失;方法选择取决于类型、兼容性、性能与业务语义。

直接说结论:别一上来就写 Array.from(new Set(arr)),先分场景讲清楚“去重对象是什么”,再匹配方法。面试官想听的不是代码,而是你对类型、相等规则、性能和边界情况的理解。
明确去重目标:基础类型还是对象数组?
这是所有回答的起点,必须先确认:
- 基础类型(数字、字符串、布尔、NaN、null、undefined):Set 是首选,它用 SameValueZero 算法,能正确识别
NaN === NaN,而indexOf或==都不行; - 对象数组(如
[{id:1}, {id:1}]):Set 失效,因为每个对象是不同引用;得按字段去重,常用 Map + 字段值作 key,或手写深比较(注意循环引用); - 混合类型(含对象、函数、NaN):Set 能处理 NaN 和基本类型,但对象仍视为不同;若需统一按 JSON 字符串去重,要小心
undefined、函数、Symbol 会被忽略。
对比核心方法,突出关键差异
不用罗列 12 种,聚焦 4 种有代表性的,讲清原理和取舍:
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
-
Set 方法:
[...new Set(arr)]—— 时间复杂度 O(n),简洁高效,支持 NaN,但不兼容 IE; -
filter + indexOf:
arr.filter((x, i) => arr.indexOf(x) === i)—— 易懂但 O(n²),且indexOf对 NaN 返回 -1,无法去重; -
Map 按字段去重(对象数组):
arr.filter((item, i, a) => !map.has(item.id) && map.set(item.id, 1))—— 精准、可控、O(n); -
对象键名法(兼容旧环境):
obj[typeof x + x]—— 注意null和undefined都转成"object",会冲突,得加类型前缀如typeof x + '|' + JSON.stringify(x)。
主动点出容易踩的坑
说到这一步,你就已经超过 80% 的候选人:
-
NaN !== NaN,所以任何基于===或==的判断(如双层 for、indexOf)都会漏掉 NaN 重复; - 对象数组用 Set 不去重,是因为内存地址不同,不是“内容相同”;
-
sort()去重会改变原顺序,且数字数组默认字典序排序([10, 2]排成[10, 2]而非[2, 10]),必须传比较函数; - 用对象做 hash 表时,
obj[1]和obj["1"]是同一个 key,基本类型自动转字符串,要注意类型混用。
收尾给出选型建议,体现工程思维
最后一句总结,让回答落地:
日常开发优先用 Set,清晰安全;需要兼容 IE 就用 Map + includes 或优化的对象键名法;对象数组一律按业务字段建索引,避免无意义的深比较;如果数据量超万级,提前考虑流式处理或后端分页去重——前端不是万能的。

















