You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Object.assign合并对象时,如何实现数组值的合并而非覆盖?

如何合并对象中相同键的数组元素而非替换?

嘿,这个问题我之前也踩过坑!Object.assign()(包括扩展运算符{...obj1, ...obj2})做的是浅层次的属性覆盖——当遇到数组这种引用类型的属性时,它只会直接用新对象的属性值替换旧对象的,不会帮你合并数组里的元素,这就是为啥你的4123数组最后只剩Peter那一项的原因。

要实现你想要的“相同键下数组合并,其他键正常保留/添加”的效果,我们需要写一个自定义的合并函数来控制逻辑。

方案一:自定义遍历合并函数

先定义你的原始对象:

const json1 = { 
  '4123': [ { name: 'John', age: '29' } ], 
  '1514': [ { name: 'Kelly', age: '25' } ] 
};
const json2 = { 
  '4123': [ { name: 'Peter', age: '53' } ], 
  '567': [ { name: 'Joost', age: '61' } ] 
};

然后写合并函数,核心逻辑是:遍历所有键,判断如果两个对象都有该键且都是数组,就合并数组;否则直接保留/添加属性:

function mergeWithArrayConcat(obj1, obj2) {
  // 创建新对象,避免修改原始对象
  const merged = { ...obj1 };

  for (const key in obj2) {
    if (obj2.hasOwnProperty(key)) {
      const existingValue = merged[key];
      const newValue = obj2[key];

      // 当两边都是数组时,合并元素
      if (Array.isArray(existingValue) && Array.isArray(newValue)) {
        merged[key] = [...existingValue, ...newValue];
      } else {
        // 非数组情况直接赋值(新键添加,旧键覆盖)
        merged[key] = newValue;
      }
    }
  }

  return merged;
}

调用函数得到结果:

const finalResult = mergeWithArrayConcat(json1, json2);
console.log(finalResult);

输出完全符合你的需求:

{
  '4123': [ { name: 'John', age: '29' }, { name: 'Peter', age: '53' } ],
  '1514': [ { name: 'Kelly', age: '25' } ],
  '567': [ { name: 'Joost', age: '61' } ]
}

方案二:用reduce简化实现

如果你喜欢更简洁的写法,可以用Object.keys和reduce来实现相同逻辑:

const mergedResult = Object.keys({ ...json1, ...json2 }).reduce((acc, key) => {
  const valFrom1 = json1[key];
  const valFrom2 = json2[key];

  if (valFrom1 && valFrom2 && Array.isArray(valFrom1) && Array.isArray(valFrom2)) {
    acc[key] = [...valFrom1, ...valFrom2];
  } else {
    // 优先取json2的值,没有则取json1的
    acc[key] = valFrom2 ?? valFrom1;
  }

  return acc;
}, {});

这个写法更偏向函数式风格,逻辑和方案一完全一致,只是表达方式不同。

为什么Object.assign不行?

再补充下原理:Object.assign()在处理属性时,会直接将源对象的属性值赋值给目标对象。如果属性值是引用类型(比如数组、对象),它只会复制引用,而不会深拷贝或者合并内容。所以当你用Object.assign(json1, json2)时,json2的4123数组会直接替换掉json1里的同键数组,而不是合并元素。

内容的提问来源于stack exchange,提问作者Kid Diamond

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:27:41