JavaScript合并两个对象时仅保留第二个对象存在属性的方法
需求说明
原有多对象合并JavaScript函数为递归深度合并逻辑,会保留前序对象中存在、但后序合并对象同名字段下不存在的嵌套子属性。现需要调整合并规则:
- 只要某属性在后序待合并对象中存在,就完整使用后序对象的该属性值
- 直接丢弃前序对象对应属性下的所有多余子内容,不再做递归合并
规则示例
- 前序对象(obj1)的
surname字段:
surname: { test: '123', other: '124' }
- 后序对象(obj2)的同名
surname字段:
surname: { test: '124' }
符合要求的合并结果中,
surname字段完全取obj2的属性值,不存在other: '124'子属性。
原有待修改代码
function merge(...objects) { function m(t, s) { Object.entries(s).forEach(([k, v]) => { t[k] = v && typeof v === 'object' ? m(t[k] || {}, v) : v; }); return t; } return objects.reduce(m, {}); } var obj1 = { name: '112', surname: { test: '123', other: '124' }, age: 151, height: '183', weight: 80 }, obj2 = { name: '114', surname: { test: '124' }, age: 151, height: 184, weight: 81 }, result = merge(obj1, obj2); console.log(result);
修改方案
问题根源在嵌套对象的合并逻辑:只要属性值是对象,原代码就会把目标对象上已有的同名属性和源对象属性递归合并,导致前面对象里多余的子属性被留下来。
修改非常简单,删掉递归合并的判断,遍历到源对象的属性时直接整值覆盖到目标对象上就行,不用再逐层合并嵌套内容:
function merge(...objects) { function m(t, s) { Object.entries(s).forEach(([k, v]) => { // 直接完整覆盖,不递归合并嵌套对象 t[k] = v; }); return t; } return objects.reduce(m, {}); } var obj1 = { name: '112', surname: { test: '123', other: '124' }, age: 151, height: '183', weight: 80 }, obj2 = { name: '114', surname: { test: '124' }, age: 151, height: 184, weight: 81 }, result = merge(obj1, obj2); console.log(result);
运行结果
修改后代码的输出如下,完全符合预期:
{ name: '114', surname: { test: '124' }, age: 151, height: 184, weight: 81 }
注:该实现为浅合并,若属性值为引用类型(对象、数组等),合并结果中的属性会和源对象共享引用。如果需要完全切断引用关联,可以在赋值前对属性值做深拷贝处理。
内容的提问来源于stack exchange,提问作者smolo
相关产品推荐
相关产品推荐

