如何深合并而不是浅合并? [英] How to deep merge instead of shallow merge?
本文介绍了如何深合并而不是浅合并?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
两者都Object.assign和 对象传播 只进行浅层合并.
Both Object.assign and Object spread only do a shallow merge.
问题示例:
// No object nesting
const x = { a: 1 }
const y = { b: 1 }
const z = { ...x, ...y } // { a: 1, b: 1 }
输出是您所期望的.但是,如果我尝试这样做:
The output is what you'd expect. However if I try this:
// Object nesting
const x = { a: { a: 1 } }
const y = { a: { b: 1 } }
const z = { ...x, ...y } // { a: { b: 1 } }
代替
{ a: { a: 1, b: 1 } }
你得到
{ a: { b: 1 } }
x 被完全覆盖,因为扩展语法只深入一层.这与 Object.assign()
相同.
x is completely overwritten because the spread syntax only goes one level deep. This is the same with Object.assign()
.
有没有办法做到这一点?
Is there a way to do this?
推荐答案
由于这个问题仍然存在,这里有另一种方法:
Since this issue is still active, here's another approach:
- ES6/2015
- 不可变(不修改原始对象)
- 处理数组(连接它们)
/**
* Performs a deep merge of objects and returns new object. Does not modify
* objects (immutable) and merges arrays via concatenation.
*
* @param {...object} objects - Objects to merge
* @returns {object} New object with merged key/values
*/
function mergeDeep(...objects) {
const isObject = obj => obj && typeof obj === 'object';
return objects.reduce((prev, obj) => {
Object.keys(obj).forEach(key => {
const pVal = prev[key];
const oVal = obj[key];
if (Array.isArray(pVal) && Array.isArray(oVal)) {
prev[key] = pVal.concat(...oVal);
}
else if (isObject(pVal) && isObject(oVal)) {
prev[key] = mergeDeep(pVal, oVal);
}
else {
prev[key] = oVal;
}
});
return prev;
}, {});
}
// Test objects
const obj1 = {
a: 1,
b: 1,
c: { x: 1, y: 1 },
d: [ 1, 1 ]
}
const obj2 = {
b: 2,
c: { y: 2, z: 2 },
d: [ 2, 2 ],
e: 2
}
const obj3 = mergeDeep(obj1, obj2);
// Out
console.log(obj3);
这篇关于如何深合并而不是浅合并?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文