Node.js中实现两个JSON对象深合并、相同键覆盖的方法
解决方案
1. Lodash 现成方案(最推荐,复杂场景容错性高)
你需要的能力Lodash已经内置,就是_.merge方法,规则完全匹配需求:
- 递归合并所有嵌套层级的对象
- 相同键以靠后传入的对象的值覆盖前者
- 非对象类型的属性直接赋值覆盖
示例代码如下:
const _ = require('lodash'); // 你的两个示例对象 const obj1 = { "title": "Test", "url": "/test", "gf": { "name": "kim", "last": "john" }, "created_at": "2021-09-08T18:40:50.152Z", "updated_at": "2021-09-08T18:54:36.387Z", "version": 9 }; const obj2 = { "gf": { "last": "Anup" }, "__originalParams": { "gf": { "last": "Anup" } } }; // 合并,注意顺序:前面是被合并对象,后面是覆盖用对象 // 第一个参数传空对象是为了避免修改原有obj1、obj2,不需要保留原对象可直接写_.merge(obj1, obj2) const merged = _.merge({}, obj1, obj2); console.log(merged);
输出结果和你给出的期望结果完全一致。
2. Ramda 现成方案
如果你使用Ramda技术栈,对应的方法是R.mergeDeepRight,语义更明确:右边传入的对象优先级更高,执行深度合并:
const R = require('ramda'); const merged = R.mergeDeepRight(obj1, obj2); console.log(merged);
效果和Lodash的merge完全一致,满足你的需求。
3. 原生手写实现(不想引入第三方库时用)
如果你的业务场景不需要处理循环引用、特殊类型(Date、RegExp等)边界情况,也可以自己手写简单的深度合并函数,参考实现:
function deepMerge(target, source) { const result = {...target}; for (const key in source) { if (source[key] instanceof Object && key in result && result[key] instanceof Object) { result[key] = deepMerge(result[key], source[key]); } else { result[key] = source[key]; } } return result; } const merged = deepMerge(obj1, obj2);
如果业务结构复杂,还是更推荐用成熟库实现,避免自行处理边界case出错。
内容的提问来源于stack exchange,提问作者Suraj Dalvi
相关产品推荐
相关产品推荐

