JavaScript数组去重7种方法解析(常用方法)
一、核心解题逻辑
所有去重方法的本质的是:识别并保留首次出现的元素,剔除重复元素。不同方法的核心差异在于「判断元素是否重复的方式」「兼容性」和「执行效率」,面试中需根据场景灵活选择。
满分答题框架(面试必备):
基础类型去重:优先用 Set(简洁高效,支持 NaN);
对象数组去重:用 Map+指定字段(按唯一键去重,适配复杂场景);
兼容旧浏览器:用优化后的对象键值法或 indexOf+遍历;
性能优先:避开 O(n²) 方法,选择 O(n) 级别的 Set/Map/对象键值法。
二、基础类型数组去重(常用方法)
基础类型指 Number、String、Boolean、NaN 等,以下方法针对这类场景展开。
1. Set 方法(推荐首选)
核心思路
利用 ES6 Set 结构「值唯一、不允许重复」的特性,自动过滤重复元素。Set 内部采用 SameValueZero 算法,可正确识别 NaN 为重复值(解决 indexOf 无法匹配 NaN 的痛点)。
代码实现(极简版+封装版)

优缺点与复杂度
✅ 优点:代码极简、执行效率高(时间复杂度 O(n))、支持 NaN 去重;
❌ 缺点:仅兼容 ES6+(IE 浏览器不支持),无法处理对象数组(对象引用不同视为不同元素);
2. indexOf + 遍历(基础朴素版)
核心思路
遍历原数组,用 indexOf() 判断当前元素是否已存在于结果数组中(返回 -1 表示不存在),不存在则加入结果数组。
代码实现

优缺点与复杂度
✅ 优点:兼容所有浏览器(包括 IE)、逻辑简单易理解;
❌ 缺点:效率低(时间复杂度 O(n²))、无法处理 NaN 重复;
3. includes + forEach(改进版,支持 NaN)
核心思路
用 includes() 替代 indexOf() 判断元素是否存在,includes() 同样采用 SameValueZero 算法,可正确识别 NaN。
代码实现

优缺点与复杂度
✅ 优点:支持 NaN 去重、逻辑清晰;
❌ 缺点:效率低(O(n²))、兼容 ES7+(比 Set 兼容性稍差);
4. filter + indexOf(函数式写法)
核心思路
用 filter() 过滤数组,仅保留「元素第一次出现的索引 === 当前遍历索引」的元素(重复元素的 indexOf 结果小于当前索引)。
代码实现

优缺点
✅ 优点:函数式编程风格、代码简洁;
❌ 缺点:无法处理 NaN、效率 O(n²);
适用场景:小数据量、不需要处理 NaN 的简单场景。
5. 对象键值法(兼容旧浏览器,需避坑)
核心思路
利用「对象键名唯一」的特性,将数组元素作为对象键名存储,避免重复。需注意对象键名会自动转为字符串,存在类型转换坑。
基础版(存在坑点)

优化版(解决类型转换坑)
通过「类型+值」拼接键名(如 `number_1`、`string_1`),区分不同类型的相同值。

优缺点与复杂度
✅ 优点:兼容旧浏览器(IE6+)、效率 O(n)、支持 NaN 去重;
❌ 缺点:基础版存在类型转换坑,优化版代码稍复杂;
三、对象数组去重(进阶场景)
实际开发中对象数组去重更常见(如按 id 去重列表数据),核心是按「唯一字段」过滤,推荐用 Map 实现。
Map + 字段去重(推荐)
核心思路
用 Map 存储已出现的字段值,遍历数组时判断字段值是否存在于 Map 中,不存在则存入 Map 并保留当前元素。Map 支持任意类型键名,比对象更灵活。
代码实现

优缺点与复杂度
✅ 优点:效率高(O(n))、灵活适配任意唯一字段、支持复杂类型键名;
❌ 缺点:兼容 ES6+;
适用场景:项目开发中对象数组去重(如表格数据、接口返回列表)。
四、关键坑点与注意事项
1. NaN 的匹配问题
indexOf/filter+indexOf:基于 === 匹配,NaN === NaN 为 false,无法去重 NaN;
Set/includes/Map:基于 SameValueZero 算法,视为 NaN 相等,可正确去重。
2. 类型转换坑
对象键值法基础版会将键名转为字符串,导致 1 和 '1'、true 和 'true' 被视为同一元素,需通过「类型+值」拼接优化。
3. 原数组修改问题
部分方法(如双重 for 循环+splice)会直接修改原数组,开发中建议返回新数组(如用 filter、扩展运算符拷贝),避免副作用。
五、性能对比与场景选择
方法 | 时间复杂度 | 兼容版本 | 适用场景 |
|---|---|---|---|
Set | O(n) | ES6+ | 基础类型、现代项目、性能优先 |
Map+字段 | O(n) | ES6+ | 对象数组、按唯一字段去重 |
优化对象键值 | O(n) | IE6+ | 旧浏览器、基础类型 |
indexOf/includes/filter | O(n²) | IE8+/ES7+ | 小数据量、简单场景 |
六、总结
1. 高频考点:Set 方法(代码极简,必写)、indexOf 与 includes 的区别(NaN 处理)、对象数组去重(Map+字段);
2. 避坑要点:NaN 匹配规则、对象键值的类型转换坑、原数组修改副作用;
3. 性能优化:大数据量优先选 O(n) 方法(Set/Map/优化对象键值),避开 O(n²) 方法;
4. 兼容性回答:现代项目用 Set/Map,需兼容 IE 则用优化对象键值法或 indexOf+遍历。
到此这篇关于JavaScript数组去重7种方法解析的文章就介绍到这了,更多相关JS数组去重内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
ES5 模拟 ES6 的 Symbol 实现私有成员功能示例
这篇文章主要介绍了ES5 模拟 ES6 的 Symbol 实现私有成员功能,结合实例形式分析了ES5 模拟 ES6 的 Symbol 实现私有成员功能相关原理、实现方法与操作注意事项,需要的朋友可以参考下2020-05-05
js中offset,client , scroll 三大元素知识点总结
在本篇文章里小编给大家整理了关于js 元素offset,client , scroll 三大系列总结,有需要的朋友们可以学习下。2019-09-09


最新评论