如何合并两个对象且不拆分数组?求技术实现方案
解决对象合并时数组不被拆分/覆盖的问题
我太懂这种踩坑的感觉了——用扩展运算符合并对象时,要么数组被直接覆盖,要么一不小心把数组拆成了一堆带索引的键值对,完全不是自己想要的效果。咱们来一步步解决这个问题!
场景1:合并对象时,保留并合并同名数组属性
如果你的两个对象有同名的数组属性,想要把数组合并而非覆盖,扩展运算符本身做不到自动合并数组(它只会浅拷贝并覆盖同名属性),这时候需要手动处理数组属性:
举个实际例子:
const obj1 = { name: "Bob", tags: ["frontend", "javascript"] }; const obj2 = { age: 28, tags: ["react", "typescript"] }; // 正确合并:保留其他属性,合并tags数组 const mergedObj = { ...obj1, ...obj2, tags: [...obj1.tags, ...obj2.tags] }; console.log(mergedObj.tags); // 输出:["frontend", "javascript", "react", "typescript"]
这里的思路是:先用扩展运算符合并所有非数组属性(或直接覆盖非数组的同名属性),然后单独处理数组属性,把两个数组合并后赋值回去。
如果担心某个对象可能没有这个数组属性,可以加个判断避免报错:
const mergedObj = { ...obj1, ...obj2, tags: [...(obj1.tags || []), ...(obj2.tags || [])] };
场景2:不小心把数组拆成了键值对(错误展开数组)
如果你的问题是不小心把数组当成对象展开了,导致数组元素变成0: 值, 1: 值这样的键值对,那你需要注意不要直接展开数组,而是把数组作为属性值完整保留:
错误示例(踩坑现场):
const obj1 = { data: [1, 2, 3] }; const obj2 = { ...obj1.data }; // 错误:展开数组会把索引作为键 // 得到:{0: 1, 1: 2, 2: 3}
正确做法:
const obj1 = { data: [1, 2, 3] }; const obj2 = { ...obj1 }; // 正确:展开对象,完整保留data数组属性 // 或者如果要合并另一个对象的数组属性: const obj3 = { otherData: [4,5] }; const mergedObj = { ...obj1, ...obj3 }; // 得到:{ data: [1,2,3], otherData: [4,5] }
通用工具函数(频繁合并时用)
如果经常需要处理这种带数组的对象合并,可以写一个简单的工具函数,自动合并数组属性、覆盖非数组属性:
function mergeObjectsWithArrays(obj1, obj2) { const merged = { ...obj1 }; for (const key in obj2) { if (Array.isArray(obj1[key]) && Array.isArray(obj2[key])) { // 两个都是数组,就合并 merged[key] = [...obj1[key], ...obj2[key]]; } else { // 非数组属性直接覆盖 merged[key] = obj2[key]; } } return merged; } // 使用示例 const objA = { a: [1,2], b: "hello" }; const objB = { a: [3,4], b: "world", c: true }; const result = mergeObjectsWithArrays(objA, objB); // 结果:{ a: [1,2,3,4], b: "world", c: true }
这样不管有多少个数组属性,都能自动合并,不用手动一个个处理。
内容的提问来源于stack exchange,提问作者Sharper
相关产品推荐
相关产品推荐

