两个对象。assign和Object spread只做浅合并。
这个问题的一个例子:
// No object nesting
const x = { a: 1 }
const y = { b: 1 }
const z = { ...x, ...y } // { a: 1, b: 1 }
输出是您所期望的。然而,如果我尝试这样做:
// 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()相同。
有办法做到这一点吗?
我发现只有2行解决方案得到深度合并在javascript。一定要告诉我你的结果。
const obj1 = { a: { b: "c", x: "y" } }
const obj2 = { a: { b: "d", e: "f" } }
temp = Object.assign({}, obj1, obj2)
Object.keys(temp).forEach(key => {
temp[key] = (typeof temp[key] === 'object') ? Object.assign(temp[key], obj1[key], obj2[key]) : temp[key])
}
console.log(temp)
临时对象将打印{a: {b: 'd', e: 'f', x: 'y'}}
这里,直走;
一个简单的解决方案,工作像Object。仅赋值deep,适用于数组,无需任何修改。
function deepAssign(target, ...sources) {
for (source of sources) {
for (let k in source) {
let vs = source[k], vt = target[k]
if (Object(vs) == vs && Object(vt) === vt) {
target[k] = deepAssign(vt, vs)
continue
}
target[k] = source[k]
}
}
return target
}
x = { a: { a: 1 }, b: [1,2] }
y = { a: { b: 1 }, b: [3] }
z = { c: 3, b: [,,,4] }
x = deepAssign(x, y, z)
console.log(JSON.stringify(x) === JSON.stringify({
"a": {
"a": 1,
"b": 1
},
"b": [ 1, 2, null, 4 ],
"c": 3
}))
编辑:
我在别的地方回答过一种深度比较两个对象的新方法。
该方法也可以用于深度合并。如果你想要植入,请留言
https://stackoverflow.com/a/71177790/1919821
我试着写一个对象。基于Object的pollyfill的assignDeep。在mdn上赋值。
(ES5)
Object.assignDeep = function (target, varArgs) { // .length of function is 2
'use strict';
if (target == null) { // TypeError if undefined or null
throw new TypeError('Cannot convert undefined or null to object');
}
var to = Object(target);
for (var index = 1; index < arguments.length; index++) {
var nextSource = arguments[index];
if (nextSource != null) { // Skip over if undefined or null
for (var nextKey in nextSource) {
// Avoid bugs when hasOwnProperty is shadowed
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
if (typeof to[nextKey] === 'object'
&& to[nextKey]
&& typeof nextSource[nextKey] === 'object'
&& nextSource[nextKey]) {
Object.assignDeep(to[nextKey], nextSource[nextKey]);
} else {
to[nextKey] = nextSource[nextKey];
}
}
}
}
}
return to;
};
console.log(Object.assignDeep({},{a:{b:{c:1,d:1}}},{a:{b:{c:2,e:2}}}))