两个对象。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()相同。

有办法做到这一点吗?


当前回答

如果你想要一个单行程序,而不需要像lodash那样庞大的库,我建议你使用deepmerge (npm install deepmerge)或deepmerge-ts (npm install deepmerge-ts)。

deepmerge也为TypeScript提供了类型,并且更加稳定(因为它比较老),但是deepmerge-ts也可用于Deno,并且从设计上看更快,尽管顾名思义是用TypeScript编写的。

一旦导入就可以了

deepmerge({ a: 1, b: 2, c: 3 }, { a: 2, d: 3 });

得到

{ a: 2, b: 2, c: 3, d: 3 }

这对于复杂的对象和数组非常有效。这是一个真正的全面解决方案。

其他回答

我在加载缓存redux状态时遇到了这个问题。如果我只是加载缓存的状态,我会遇到错误的新应用程序版本与更新的状态结构。

前面已经提到过,lodash提供了merge函数,我使用了这个函数:

const currentInitialState = configureState().getState();
const mergedState = _.merge({}, currentInitialState, cachedState);
const store = configureState(mergedState);

有一些维护良好的库已经做到了这一点。npm注册表中的一个例子是merge-deep

我不喜欢现有的解决方案。所以,我开始写我自己的。

Object.prototype.merge = function(object) {
    for (const key in object) {
        if (object.hasOwnProperty(key)) {
            if (typeof this[key] === "object" && typeof object[key] === "object") {
                this[key].merge(object[key]);

                continue;
            }

            this[key] = object[key];
        }
    }

    return this;
}

我希望这能帮助那些努力理解正在发生的事情的人。我在这里看到了很多无意义的变量。

谢谢

我们可以使用$.extend(true,object1,object2)进行深度合并。值true表示递归合并两个对象,修改第一个对象。

美元扩展(真的,目标,对象)

ES5的一个简单解决方案(覆盖现有值):

function merge(current, update) { Object.keys(update).forEach(function(key) { // if update[key] exist, and it's not a string or array, // we go in one level deeper if (current.hasOwnProperty(key) && typeof current[key] === 'object' && !(current[key] instanceof Array)) { merge(current[key], update[key]); // if update[key] doesn't exist in current, or it's a string // or array, then assign/overwrite current[key] to update[key] } else { current[key] = update[key]; } }); return current; } var x = { a: { a: 1 } } var y = { a: { b: 1 } } console.log(merge(x, y));