两个对象。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()相同。
有办法做到这一点吗?
这很简单,也很有效:
let item = {
firstName: 'Jonnie',
lastName: 'Walker',
fullName: function fullName() {
return 'Jonnie Walker';
}
Object.assign(Object.create(item), item);
解释:
create()创建新对象。如果你传递参数给函数,它将创建你的对象与其他对象的原型。如果你在一个对象的原型上有任何函数它们会被传递给另一个对象的原型。
object .assign()合并两个对象并创建一个全新的对象,它们不再有引用。这个例子对我来说很好。
我把这里所有的答案都看了一遍,然后拼凑出了一个我自己的答案。现有的大多数答案都不是我想要的方式。
这对于2021年来说是相当可怕的,所以任何改善的建议,我都洗耳恭听!
这是在Typescript中
type Props = Record<string, any>
export const deepMerge = (target: Props, ...sources: Props[]): Props => {
if (!sources.length) {
return target
}
Object.entries(sources.shift() ?? []).forEach(([key, value]) => {
if (!target[key]) {
Object.assign(target, { [key]: {} })
}
if (
value.constructor === Object ||
(value.constructor === Array && value.find(v => v.constructor === Object))
) {
deepMerge(target[key], value)
} else if (value.constructor === Array) {
Object.assign(target, {
[key]: value.find(v => v.constructor === Array)
? target[key].concat(value)
: [...new Set([...target[key], ...value])],
})
} else {
Object.assign(target, { [key]: value })
}
})
return target
}
平面数组使用[…]删除重复值。新的(…)]。
嵌套数组使用concat连接。
我发现只有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'}}