js数组去重需据场景选择:基础类型用[...new set(arr)],兼容老环境用filter+indexof,对象按字段去重推荐map,深度去重慎用json.stringify,生产环境建议lodash。

JS 数组去重有多种场景和写法,关键看是否保留顺序、是否处理对象、是否兼容老环境。下面按常见需求分类整理,直接可查可用。
基础类型数组(数字/字符串)去重
最常用的是 Set + 扩展运算符,简洁高效,自动保持原顺序:
const arr = [1, 2, 2, 3, 'a', 'a', 4]; const unique = [...new Set(arr)]; // [1, 2, 3, 'a', 4]
兼容性要求高(如需支持 IE)时,可用 filter + indexOf:
const unique = arr.filter((item, index) => arr.indexOf(item) === index);
对象数组按某字段去重
比如根据 id 或 name 去重,推荐用 Map 记录已见 key,性能好且逻辑清晰:
const users = [{id: 1, name: 'Alice'}, {id: 2, name: 'Bob'}, {id: 1, name: 'Alice'}];
const uniqueBy = (arr, key) => {
const seen = new Map();
return arr.filter(item => {
if (seen.has(item[key])) return false;
seen.set(item[key], true);
return true;
});
};
uniqueBy(users, 'id'); // [{id: 1, name: 'Alice'}, {id: 2, name: 'Bob'}]
也可用 reduce 实现单行精简版(适合简单场景):
arr.reduce((acc, cur) => acc.some(x => x.id === cur.id) ? acc : [...acc, cur], []);
深度去重(含嵌套对象或数组)
原生 JS 不直接支持,需序列化判断。注意:JSON.stringify 有局限性(如函数、undefined、Symbol 会丢失,顺序不同对象可能被误判):
const deepUnique = (arr) => {
const seen = new Set();
return arr.filter(item => {
const str = JSON.stringify(item);
if (seen.has(str)) return false;
seen.add(str);
return true;
});
};
生产环境建议用 Lodash 的 uniqWith(eq) 或自定义比较函数替代。
一行函数封装(实用速查)
把常用逻辑打包成可复用函数:
-
基础去重:
const uniq = arr => [...new Set(arr)]; -
字段去重:
const uniqBy = (arr, key) => arr.filter((x, i, a) => a.findIndex(y => y[key] === x[key]) === i); -
自定义比较去重:
const uniqWith = (arr, fn) => arr.filter((x, i) => arr.findIndex(y => fn(x, y)) === i);
不复杂但容易忽略细节,用前看清数据类型和环境约束。











