- 在日常开发中经常要使用到对象的合并
- js也提供了
Object.assign(target, ...sources)
的API用来合并对象,也可以使用展开运算符实现合并比如
let obj1 = {a:1,b:2,c:3}
let obj2 = {a:2,b:4,d:3}
let newObj = {...obj1,...obj2}
let newObj2 = Object.assign(obj1,obj2)
console.log(newObj,newObj2)
//{ a: 2, b: 4, c: 3, d: 3 } { a: 2, b: 4, c: 3, d: 3 }
- 但是这样会有一个问题,就是无法合并多层结构的对象比如
let obj1 = {c:{q:1,w:2}}
let obj2 = {c:{e:3}}
let newObj = {...obj1,...obj2}
let newObj2 = Object.assign(obj1,obj2)
console.log(newObj,newObj2)
//{ c: { e: 3 } } { c: { e: 3 } }
- 我们可以看到c属性只是进行了简单的替换
- 所以今天就解决一下多层合并的问题
1.思路分析
1)我们要实现,如果目标对象中的属性具与源对象有相同的键并且相同的键的值也为对象,则将此对象也进行相同规则的合并,否则属性将被源对象中的属性覆盖,并且不同的键会同时存在
2)首先要理解,target是主体,遍历sources对象,判断如果target对象存在相同键并且同时为对象,递归调用合并方法,否则将target对象键值替换
3)返回新对象
function assiginObj(target = {},sources= {}){
let obj = target;
if(typeof target != 'object' || typeof sources != 'object'){
return sources; // 如果其中一个不是对象 就返回sources
}
for(let key in sources){
// 如果target也存在 那就再次合并
if(target.hasOwnProperty(key)){
obj[key] = assiginObj(target[key],sources[key]);
} else {
// 不存在就直接添加
obj[key] = sources[key];
}
}
return obj;
}
测试
let a = {
a:{a:1,b:2,c:3},
c:12,
z:15
}
let b = {
a:{a:12,e:13},
b:13,
z:16
}
console.log(assiginObj(a,b))
//{ a: { a: 12, b: 2, c: 3, e: 13 }, c: 12, z: 16, b: 13 }