一个关于对象深合并的问题?

JayZangwill
  • 611

现有两个对象:

var obj1 = {
    students: {
        lingxuan: {
            name: 'lingxuan',
            addr: 'guangzhou'
        }
    }
}

var obj2 = {
    students: {
        lingxuan: {
            mobile: '1823430****'
        }
    },
    teachers: {
        sam: {
            name: 'sam'
        }
    }
}

我想通过deepMerge(obj1, obj2)以后最终能得到(要用原生js):

newObj = {
    students: {
        lingxuan: {
            name: 'lingxuan',
            addr: 'guangzhou',
            mobile: '1823430****'
        }
    },
    teachers: {
         sam: {
            name: 'sam'
         }
    }
}

这个题目想了很久没想出来怎么解,也想过用递归和Object.assign但是得不到想要的结果,希望大神指点指点。

回复
阅读 6.7k
3 个回答

感谢@小明同学的提醒,翻看了jQuery的源码有了思路,于是代码如下:

function deepMerge(obj1, obj2) {
    var key;
    for(key in obj2) {
        // 如果target(也就是obj1[key])存在,且是对象的话再去调用deepMerge,否则就是obj1[key]里面没这个对象,需要与obj2[key]合并
        obj1[key] = obj1[key] && obj1[key].toString() === "[object Object]" ?
        deepMerge(obj1[key], obj2[key]) : obj1[key] = obj2[key];
    }
    return obj1;
}

参考zepto的extend方法,可以依着这个思路根据自己的需求进行修改

function DeepExtend(obj1,obj2){
    if(Object.prototype.toString.call(obj1) === '[object Object]' && Object.prototype.toString.call(obj2) === '[object Object]'){
        for( prop2 in obj2){//obj1无值,都有取obj2
            if(!obj1[prop2]){
                obj1[prop2] =obj2[prop2];
            }else{//递归赋值
                    obj1[prop2]=DeepExtend(obj1[prop2],obj2[prop2]);
            }
        }
    }else if(Object.prototype.toString.call(obj1) === '[object Array]' && Object.prototype.toString.call(obj2) === '[object Array]'){
        // 两个都是数组,进行合并
        obj1=obj1.concat(obj2);
    }else{//其他情况,取obj2的值
        obj1 = obj2;
    }
    return obj1;
    
}

可以看下lodash的merge

var object = {
  'a': [{ 'b': 2 }, { 'd': 4 }]
};
 
var other = {
  'a': [{ 'c': 3 }, { 'e': 5 }]
};
 
_.merge(object, other);
// => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
你知道吗?

宣传栏