深拷贝实现属性的深度合并核心是递归处理嵌套对象,确保同名嵌套属性逐层合并而非整体替换;需合理处理数组、date、regexp等特殊类型,且不修改原对象;手动递归实现轻量可控,lodash的_.merge()更可靠全面,而json.parse(json.stringify())不适用于深度合并。

JavaScript 中深拷贝实现属性的深度合并,核心在于“递归处理嵌套对象”,而不是简单覆盖或浅层复制。它要确保:同名嵌套对象的属性被逐层合并,而非整个替换;数组、日期、正则等特殊类型也能合理处理;原始对象不被意外修改。
用递归函数手动实现深度合并
这是最可控的方式,适合轻量级场景且无需引入外部依赖。关键逻辑是:遇到对象类型(且非 null、非数组)就递归调用自身,其他类型直接赋值。
- 目标对象不存在时,初始化为空对象
- 遍历源对象每个键,若目标中对应键也是对象且源中也是对象,则递归合并;否则直接赋值
- 注意跳过 null、undefined 和数组(数组通常按整体替换,除非你明确要 concat)
示例代码:
function deepMerge(target, source) {if (typeof target !== 'object' || target === null || typeof source !== 'object' || source === null) return source;
for (const key in source) {
if (source.hasOwnProperty(key)) {
if (key in target && typeof target[key] === 'object' && typeof source[key] === 'object' && !Array.isArray(target[key]) && !Array.isArray(source[key])) {
target[key] = deepMerge(target[key], source[key]);
} else {
target[key] = source[key];
}
}
}
return target;
}
用 Lodash 的 _.merge() 实现可靠深度合并
这是生产环境最推荐的做法。_.merge() 不仅处理普通对象和嵌套对象,还支持 Map、Set、Date、RegExp 等类型,并能正确处理数组(默认按索引合并,不 concat)。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 安装:
npm install lodash - 使用:
const merged = _.merge({}, obj1, obj2);—— 第一个参数传空对象,避免修改原数据 - 行为特点:obj2 中的嵌套属性会与 obj1 同路径属性合并,不会整层替换
例如:{ a: { x: 1 } } 和 { a: { y: 2 } } 合并后是 { a: { x: 1, y: 2 } },不是 { a: { y: 2 } }。
避开 JSON.parse(JSON.stringify()) 的坑
这个组合常被误当作“深拷贝方案”,但它**不能用于深度合并**,只适合纯数据对象的粗略拷贝:
- 会丢失函数、undefined、Symbol、Date、RegExp、Map、Set 等类型
- 循环引用直接报错
- 即使先深拷再 Object.assign,也只是把第二个对象整个覆上去,嵌套结构依然被替换,不是合并
所以它只适合“先拷一份,再浅合并”,但结果仍是浅合并效果,达不到深度合并目的。
注意深合并与深拷贝的区别
深拷贝(deep clone)是复制一份独立副本;深度合并(deep merge)是把多个对象的结构“缝合”起来。两者目标不同:
- 如果你只是想备份一个对象再改,用深拷贝就够了
- 如果你要融合配置项、覆盖默认设置、合并 API 响应,就必须用深度合并
- 很多库(如 Lodash)把两者分开:_.cloneDeep() vs _.merge()
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










