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

如何合并含相同嵌套属性的对象并保留所有属性?是否需用扩展运算符?

深度合并JavaScript嵌套对象的解决方案

你遇到的问题其实是浅合并 vs 深度合并的区别——Object.assign()和直接用扩展运算符{...obj1, ...obj2}都是浅合并,只会处理对象的第一层属性,嵌套的子对象会直接被后面的对象覆盖,而不是合并它们的属性。

为什么扩展运算符单独用不行?

先看个例子,用扩展运算符试试:

let obj1 = {'foo': 'bar', 'far': {'tst': 1}};
let obj2 = {'far': {'other': 'token'}};
const merged = {...obj1, ...obj2};
console.log(merged); 
// 输出:{"foo":"bar","far":{"other":"token"}}

结果和Object.assign()一样,嵌套的far被完全替换了,因为扩展运算符只复制第一层的键值对,对于far这个键,后面的obj2.far直接覆盖了obj1.far的引用。

那怎么实现你要的深度合并呢?有几种方案:


方案1:手动处理已知的嵌套结构

如果你的对象结构是固定的、嵌套层级不多,可以直接用扩展运算符逐层合并:

const merged = {
  ...obj1, // 复制第一层属性
  far: {
    ...obj1.far, // 合并嵌套的far对象的属性
    ...obj2.far
  }
};
console.log(merged);
// 输出:{"foo":"bar","far":{"tst":1,"other":"token"}}

这种方法简单直接,但缺点是如果嵌套层级深或者结构不确定,写起来就很麻烦。


方案2:写一个通用的深度合并函数

如果需要处理任意结构的嵌套对象,可以写一个递归的深度合并函数,自动处理所有层级的对象:

// 判断是否是纯对象(排除数组、null等)
function isObject(item) {
  return item && typeof item === 'object' && !Array.isArray(item);
}

function deepMerge(target, ...sources) {
  // 如果没有源对象了,直接返回目标对象
  if (!sources.length) return target;
  const currentSource = sources.shift();

  // 如果目标和当前源都是对象,就递归合并
  if (isObject(target) && isObject(currentSource)) {
    for (const key in currentSource) {
      if (isObject(currentSource[key])) {
        // 如果目标对象没有这个键,先初始化一个空对象
        if (!target[key]) Object.assign(target, { [key]: {} });
        // 递归合并子对象
        deepMerge(target[key], currentSource[key]);
      } else {
        // 非对象属性直接覆盖赋值
        Object.assign(target, { [key]: currentSource[key] });
      }
    }
  }

  // 继续合并剩下的源对象
  return deepMerge(target, ...sources);
}

// 使用示例
const obj1 = {'foo': 'bar', 'far': {'tst': 1}};
const obj2 = {'far': {'other': 'token'}};
const mergedObj = deepMerge({}, obj1, obj2); // 传入空对象作为目标,避免修改原对象
console.log(mergedObj);
// 输出:{"foo":"bar","far":{"tst":1,"other":"token"}}

这个函数可以处理多层嵌套的对象,还可以扩展支持数组合并(如果需要的话),适合通用场景。


方案3:使用ES2023的Object.merge()(推荐,需注意兼容性)

ES2023标准引入了Object.merge()方法,它原生支持深度合并,完全符合你的需求:

const obj1 = {'foo': 'bar', 'far': {'tst': 1}};
const obj2 = {'far': {'other': 'token'}};
const mergedObj = Object.merge({}, obj1, obj2);
console.log(mergedObj);
// 输出:{"foo":"bar","far":{"tst":1,"other":"token"}}

不过要注意,这个API比较新,目前支持的环境包括:

  • 现代浏览器(Chrome 118+、Firefox 119+、Safari 17.1+)
  • Node.js 20.0.0+
    如果你的运行环境支持,这是最简洁的解决方案。

总结一下:扩展运算符本身不能直接实现深度合并,但可以用它来辅助处理单层合并;如果要深度合并,要么手动处理嵌套结构,要么用递归函数,或者用原生的Object.merge()(环境允许的话)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:35:21