当然可以!下面是【前端面试题】:JavaScript 数组去重的几种常见方法,涵盖基础写法进阶技巧性能对比场景推荐,非常适合用于简历项目描述、技术博客、面试复习等场合。


🔍 [前端面试题]:JavaScript 数组去重的几种方法(含详细解析)

🧪 示例输入:

const arr = [1, 2, 2, 3, 4, 4, 5, '5', NaN, NaN, null, null, undefined, undefined];

✅ 方法一:使用 Set

const uniqueArr = [...new Set(arr)];
console.log(uniqueArr);

📌 原理:

  • Set 是 ES6 新增的数据结构,天然去重。
  • 注意:Set 去重是值相等,但不同类型不会去除(如 5 与 '5' 都保留)。

✅ 适合场景:

  • 快速处理基本类型数组去重;
  • 无需关心数据类型严格一致。

✅ 方法二:使用 filter + indexOf

const uniqueArr = arr.filter((item, index) => arr.indexOf(item) === index);
console.log(uniqueArr);

📌 原理:

  • indexOf 会返回第一个出现的位置,若当前位置不是第一次出现,则说明是重复项。
  • 缺点:性能较差,嵌套循环时间复杂度为 O(n²)。

✅ 适合场景:

  • 面试展示思路时可用;
  • 小数据量处理场景。

✅ 方法三:使用 reduce + includes

const uniqueArr = arr.reduce((acc, cur) => {
  if (!acc.includes(cur)) acc.push(cur);
  return acc;
}, []);
console.log(uniqueArr);

📌 原理:

  • reduce 控制遍历流程,includes 判断是否已存在。
  • 支持自定义逻辑扩展,如自定义比较函数。

✅ 适合场景:

  • 适合展示函数式编程思维;
  • 可变式逻辑适合扩展场景。

✅ 方法四:使用 Map 或 Object 缓存(高性能)

function unique(arr) {
  const seen = new Map();
  return arr.filter(item => {
    return !seen.has(item) && seen.set(item, 1);
  });
}
console.log(unique(arr));

📌 原理:

  • 利用 Map 的键唯一性,实现一次遍历去重;
  • 相较 includesindexOf 性能更好,时间复杂度 O(n)。

✅ 适合场景:

  • 中大型数组去重;
  • 兼顾性能与清晰度。

✅ 方法五:处理复杂对象数组(按某字段去重)

const objArr = [
  { id: 1, name: 'A' },
  { id: 2, name: 'B' },
  { id: 1, name: 'A' }
];

const uniqueObjArr = objArr.filter((item, index, self) =>
  index === self.findIndex(t => t.id === item.id)
);
console.log(uniqueObjArr);

📌 原理:

  • 利用 findIndex 查找首个匹配对象,保留唯一项。

✅ 适合场景:

  • 对象数组去重,如根据 ID 唯一标识去重。

📊 性能对比总结

方法性能兼容性简洁度是否支持复杂数据
Set★★★★ES6+★★★★★否(值比较)
filter + indexOf★★☆ES5+★★★
reduce + includes★★☆ES5+★★★
Map★★★★ES6+★★★★
对象数组去重★★★ES5+★★★✅ 支持按字段

📌 面试加分点

  • 了解时间复杂度:如 includes 是 O(n),而 Set 查找是 O(1)。
  • 熟悉基础类型和引用类型的去重差异。
  • 能根据场景选择合适的方式(如 Map 用于高性能,filter 用于简单小数组)。