最简洁可靠的方式是使用 set 构造函数配合扩展运算符([...new set(arr)]),它自动保留首次出现的元素、不改变原始顺序、兼容基础类型,时间复杂度接近 o(n)。

JavaScript 对无序数组去重,最简洁可靠的方式是使用 Set 构造函数配合扩展运算符([...new Set(arr)]),它自动保留首次出现的元素,不改变原始顺序,且兼容所有可比较类型(数字、字符串、布尔值等)。
用 Set 去重(推荐,适用于大多数情况)
Set 会自动过滤重复值,并按插入顺序保存唯一项。对无序数组来说,这恰好保留了“第一次出现的位置”,符合常规去重要求。
- 写法简单:
const unique = [...new Set(arr)]; - 支持基础类型(
1, 'a', true)和引用类型(但注意:对象/数组本身不会被深层比较,两个不同对象即使内容相同也会被视为不同) - 性能好,时间复杂度接近 O(n)
处理对象数组去重(按某个字段)
如果数组里是对象(比如 [{id: 1, name: 'A'}, {id: 2, name: 'B'}, {id: 1, name: 'C'}]),需按指定属性(如 id)去重:
- 可用
Array.prototype.filter()配合Map或Set记录已见的 key: const seen = new Set(); const unique = arr.filter(item => !seen.has(item.id) && seen.add(item.id));- 也可用
reduce累积唯一对象,逻辑更清晰但稍长
兼容旧环境或需要自定义逻辑时用 filter + indexOf
若需支持 IE 或要控制去重逻辑(例如保留最后一次出现的元素),可用 filter 和 indexOf:
- 保留首次出现:
arr.filter((item, i) => arr.indexOf(item) === i) - 保留末次出现:
arr.filter((item, i) => arr.lastIndexOf(item) === i) - 注意:该方法对对象/数组无效(因为
indexOf做的是引用比较,不是值比较)
注意点:哪些情况会失效?
上述方法在以下场景需特别处理:
-
NaN:Set 和
indexOf都能正确识别 NaN 是重复的(ES6 规范中NaN === NaN为 false,但 Set 内部做了特殊处理) -
+0 和 -0:默认视为相等(JS 中
+0 === -0为 true),如需区分,得手动深比较 -
对象/数组深层去重:必须序列化(如
JSON.stringify)或用 Lodash 的uniqBy,但要注意函数、undefined、Date 等无法被 JSON 安全序列化
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











