JS数组去重需分层决策:基础类型小数据用[...new Set(arr)],大数据改Array.from(new Set(arr));对象数组用Map按字段索引;混合类型手写逻辑;统一封装工具函数并加断言;避免伪优化,压测监控落地。

在项目中落地 JS 数组去重性能优化,核心不是“选一个方法写完就跑”,而是根据数据特征、运行环境和业务约束做分层决策。下面从真实开发场景出发,给出可直接套用的落地路径。
明确数据类型与规模,匹配去重策略
不同数据量级和元素类型,最优解完全不同:
-
基础类型(数字/字符串/布尔值)且数据量 ≤ 10 万:直接用
[...new Set(arr)]。简洁、保序、自动处理NaN和undefined,现代浏览器全覆盖。 -
基础类型但数据量 ≥ 50 万(如日志清洗、埋点聚合):仍用
Set,但避免链式调用造成中间数组;改用Array.from(new Set(arr))更可控,利于后续加调试钩子或内存监控。 -
对象数组(如
[{id:1,name:'a'}, {id:1,name:'b'}]):禁用JSON.stringify做键(结构稍变即失效、无性能保障);改用Map按字段索引:arr.filter(item => !map.has(item.id) && map.set(item.id, true)) - 混合类型或含函数/正则等不可序列化值:必须手写逻辑判断,优先提取关键标识字段,而非盲目深比较。
封装成可配置工具函数,避免重复造轮子
不要每个文件都写一遍 new Set。统一收口,支持常见扩展:
- 默认导出基础去重:
export const unique = arr => [...new Set(arr)] - 提供按字段去重版本:
export const uniqueBy = (arr, key) => { const map = new Map(); return arr.filter(item => !map.has(item[key]) && map.set(item[key], 1)); } - 对敏感场景(如金融计算)加轻量断言:
if (arr.length > 1e6) console.warn('large array unique: consider streaming')
警惕“伪优化”陷阱,关注真实瓶颈
很多团队过早优化,反而引入新问题:
-
别为了兼容 IE11 强行降级用
filter + indexOf:该方法在 10 万数据时比Set慢 50 倍以上,用户感知明显卡顿;IE11 市场份额已低于 0.2%,应通过构建工具(如 Babel + core-js)按需 polyfillSet,而非放弃原生能力。 -
排序去重(
sort() + 遍历相邻)不保序,慎用于 UI 列表渲染:后端返回顺序常含业务含义(如热度、时间),打乱后可能引发资损。 -
避免在循环中反复创建
Set或Map:比如在 React 渲染函数里每次调用都新建,会触发频繁 GC;应提升到组件外或用useMemo缓存结果。
上线前必做两件事:压测 + 监控
性能优化不能只靠理论推演:
- 用真实数据集(如线上采样 10 万条用户标签)跑本地 benchmark,对比耗时与内存占用;
performance.now()足够准,无需引入额外库。 - 在关键路径加入轻量埋点,例如:
const start = performance.now();<br> const result = unique(largeArr);<br> console.log(`[unique] ${largeArr.length} items → ${result.length}, cost: ${performance.now() - start}ms`);
上线后通过日志平台聚合分析,看是否出现异常毛刺。











