JavaScript合并对象数组属性需先提取同名数组字段,再用flat()扁平化、Set去重,最后重组对象;通用函数可批量处理指定键,注意避免Object.assign覆盖及类型校验错误。

JavaScript 中合并多个对象的数组属性,核心在于:先提取所有对象中同名的数组字段,再用 concat()、展开运算符([...arr1, ...arr2])或 flat() 合并,最后重新组装成新对象。关键不是简单地用 Object.assign 或展开对象,而是按需“提取→合并→赋值”。
提取并合并指定数组属性
假设你有一组配置对象,每个都有 tags 和 roles 这样的数组字段,想把它们分别聚合成一个去重后的总数组:
- 用
map提取所有对象的tags数组,再用flat()扁平化,最后用[...new Set(...)]去重 - 对
roles做同样操作 - 组合成新对象,保留其他非数组字段(如取第一个对象的
name)
示例:
const items = [{ name: "A", tags: ["js", "web"], roles: ["dev"] },
{ name: "B", tags: ["node", "api"], roles: ["dev", "ops"] },
{ name: "C", tags: ["js"], roles: ["test"] }
];
const merged = {
name: items[0].name, // 或按需处理
tags: [...new Set(items.map(i => i.tags).flat())],
roles: [...new Set(items.map(i => i.roles).flat())]
};
// → { name: "A", tags: ["js", "web", "node", "api"], roles: ["dev", "ops", "test"] }
通用函数:按键名批量合并数组属性
如果经常要合并不同字段,可封装一个复用函数:
立即学习“Java免费学习笔记(深入)”;
在调试 Java 后端 API 故障时使用此技能,尤其适用于以下任务:分析日志、跨 Controller、Service 和 Mapper 层追踪请求、定位异常根因、检查 SQL 执行或参数流转,以及生成简洁的诊断结论与修复方案。
- 接收对象数组 + 要合并的键名列表(如
["tags", "roles"]) - 对每个键,过滤出有该属性且为数组的值,再扁平、去重
- 支持传入自定义合并逻辑(如不去重、保留顺序、去重但按首次出现排序)
简版实现:
function mergeArrayProps(arr, keys) {return keys.reduce((acc, key) => {
const values = arr
.map(obj => Array.isArray(obj[key]) ? obj[key] : [])
.flat();
acc[key] = [...new Set(values)];
return acc;
}, {});
}
mergeArrayProps(items, ["tags", "roles"]);
// → { tags: [...], roles: [...] }
保留原始结构 + 合并嵌套数组
若对象结构更复杂(比如 permissions: [{ action: "read" }, { action: "write" }]),而你想合并整个数组(不扁平元素),就不用 flat(),直接 concat 或展开:
items.map(i => i.permissions).reduce((a, b) => a.concat(b), [])[].concat(...items.map(i => i.permissions))-
items.flatMap(i => i.permissions)(推荐,语义清晰)
注意:flatMap 不会深度扁平,只展开一层,适合合并数组类型的字段。
避免常见错误
容易踩的坑:
- 直接
Object.assign({}, ...items)—— 后面对象的数组会完全覆盖前面的,不是合并 - 用
push.apply或concat但没处理undefined或非数组值,导致TypeError - 用
flat()时没加参数(默认只扁平一层),而嵌套过深需flat(Infinity)(慎用) - 去重时用
JSON.stringify判断对象数组相等 —— 不可靠,应先标准化或用库(如 Lodash 的uniqWith)

















