首页 > 行业资讯 > 严选问答 >

问 js 数组去重的方法 多种实现方案对比

2026-11-08 17:00:10
最佳答案

答

js 数组去重就是把数组里面重复出现的元素剔除,只保留一份,是前端开发非常高频的基础操作,常用方案包含 Set 结构去重 filter 加 indexOf 双重循环遍历 reduce 利用对象键名去重这几类,不同方案在兼容性 性能 数据类型支持上差别很大,简单基础类型优先推荐 Set 写法,对象类型数组不能直接用 Set,需要自定义判断规则。需要做 js 数组去重的根本原因,接口返回数据 用户录入数据 计算生成的数据经常会出现重复项,如果不去重就直接渲染页面 统计计算,会造成重复渲染 统计数值错误,而且不同数据类型判断相等的规则不一样,比如 NaN 引用类型对象 空字符串,普通全等判断会有坑,所以要根据业务数据类型选择对应的 js 数组去重方法。

主流方案对照表

方法名称核心原理优点缺点适用场景
Set 去重利用 Set 自动不存储重复值代码最短 ES6 原生无法处理对象数组 低版本 IE 不支持数字 字符串 布尔 NaN 基础类型
filter 加 indexOf只保留第一次出现的元素兼容性较好NaN 无法识别 大数据性能一般老项目兼容环境 基础类型
双重 for 循环逐个对比元素 标记重复项兼容所有旧浏览器时间复杂度高 大数据很慢老旧浏览器兼容项目
reduce 去重累加器记录已经出现元素灵活可扩展写法理解门槛稍高需要自定义判断逻辑
对象键名去重把元素转成对象 key大数据性能高类型会隐式转换 容易误判纯字符串数字大数据数组

各类方法详细说明

Set 去重

ES6 新增 Set 集合,Set 本身特性就是成员唯一,不会存放重复值,把原数组传入 Set 构造函数,再用 Array.from 或者扩展运算符转回数组,就完成 js 数组去重。这个方案最大优势是可以正确识别 NaN,因为 Set 内部判断相等的规则和全等不一样,能识别 NaN 等于 NaN,但是对象是引用比较,两个内容一模一样的对象,Set 依然判定为不重复,这点一定要注意。

filter 加 indexOf

遍历数组,用 indexOf 查找当前元素在数组里面第一次出现的下标,如果当前下标等于第一次出现下标,就保留这个元素。这个方案兼容 ES5 环境,但是 indexOf 内部使用全等判断,NaN 使用 indexOf 永远找不到,所以这种 js 数组去重方法遇到 NaN 会失效。

双重循环遍历

外层循环取出每一个元素,内层循环对比后面所有元素,如果发现相等就删除重复项。这个方案兼容性最强,很早版本浏览器都可以运行,但是循环嵌套,数组长度很大的时候运算耗时明显上升,数组上万条数据的时候不推荐使用。

reduce 去重

使用 reduce 维护一个累计结果数组,每次遍历原数组元素,判断累计数组里面是否已经存在这个元素,如果不存在就追加进去。这个 js 数组去重方法优势是可以自定义判断函数,基础类型和对象数组都可以改造实现,灵活度高。

对象键名去重

创建空对象,遍历数组,把元素转为字符串当作对象的键,如果键不存在就存入结果数组,同时给对象标记这个键。这个方法大数据量性能很好,但是存在隐式类型转换,比如数字 1 和字符串 "1" 会被当成同一个键,业务里面要特别小心这个坑。

对象数组去重补充说明

普通 js 数组去重方法不能直接处理对象数组,因为对象比较是引用地址对比,哪怕两个对象里面所有属性值都相同,引用地址不一样也不会判定重复。对象数组去重一般是指定唯一标识字段,比如 id,遍历的时候判断结果数组里面是否已经存在相同 id 的对象,存在就跳过,不存在就 push 进新数组。

选型步骤

1 先确认数组里面的数据类型,是基础类型还是对象类型

2 确认项目浏览器兼容要求,是否需要支持老 IE

3 确认数组数据量大小,小数据优先代码简洁,大数据优先高性能方案

4 如果存在 NaN,避开 indexOf 方案,优先选择 Set 或者自定义 reduce 方案

5 如果是对象数组,放弃 Set indexOf 这类基础方案,改成根据唯一字段自定义去重逻辑

【常见问题】

问题 1 js 数组去重的时候为什么 Set 不能去除相同内容对象

回答 1 js 数组去重使用 Set 的时候,对象是引用类型,Set 对比的是内存引用地址,两个属性完全一样的对象内存地址不同,所以 Set 不会判定重复,对象数组需要单独写 js 数组去重逻辑。

问题 2 js 数组去重哪种方法性能最好

回答 1 小数据量差别不大,超大数据量优先对象键名去重,其次是 Set,双重循环的 js 数组去重方法性能最差,不适合大数据场景。

问题 3 js 数组去重为什么 indexOf 方案无法去除 NaN

回答 1 indexOf 底层使用全等运算符判断,NaN 和任何值都不相等,包括自身,所以 indexOf 查找 NaN 永远返回负一,这种 js 数组去重方法遇到 NaN 就会失效。

问题 4 js 数组去重之后原数组会改变吗

回答 1 绝大多数 js 数组去重写法都是生成新数组,原数组保持不变,如果需要直接修改原数组,需要额外写 splice 删除重复元素的写法。

【免责申明】

本文内容仅用于前端技术学习参考,不同 ES 版本浏览器支持情况存在差异,实际业务请结合项目兼容要求测试,不构成代码方案强制选型建议。