Categories
JavaScript Answers

How to Deep Merge JavaScript Objects?

Spread the love

The Object.assign method or the spread operator lets us shallow merge JavaScript objects.

This means that only the first level is merged but the deeper are levels are still referencing the original object.

Deep merging ensures that all levels of the objects we merge into another object are copied instead of referencing the original objects.

In this article, we’ll look at how to deep merge JavaScript objects.

Merging Recursively

To deep merge JavaScript objects, we’ve to merge each level recursively ourselves.

To do this, we’ve to write our own function.

For example, we can write:

const isObject = (item) => {
  return (item && typeof item === 'object' && !Array.isArray(item));
}

const mergeDeep = (target, ...sources) => {
  if (!sources.length) return target;
  const source = sources.shift();

if (isObject(target) && isObject(source)) {
    for (const key in source) {
      if (isObject(source[key])) {
        if (!target[key]) Object.assign(target, {
          [key]: {}
        });
        mergeDeep(target[key], source[key]);
      } else {
        Object.assign(target, {
          [key]: source[key]
        });
      }
    }
  }

  return mergeDeep(target, ...sources);
}

const merged = mergeDeep({
  a: 1
}, {
  b: {
    c: 123
  }
});
console.log(merged)

First, we create the isObject helper function by checking if the item parameter is truthy and it’s an object that’s not an array.

We use the typeof operator to check if the object is an object.

If it’s truthy and its type is an object, then it must be an object.

Then we check that the object isn’t an array by using the Array.isArray method.

Next, we create the mergeDeep method to merge multiple objects into the target object.

To do this, we first check if there’re anything stored in sources .

If there’s none, then we return the target object since there’s no 2nd and subsequent arguments.

Next, we check if target and source are objects.

We get source by getting the first item from the source array with shift .

We loop through the keys of source with the for-in loop.

If the property is an object, then we merge an empty object into the target object with Object.assign .

Then we call mergeDeep to merge the keys inside the object property of source into the object recursively.

Otherwise, we have a primitive property value, and we call Object.assign to merge it into the object directly.

Finally, we return the merged object at the end.

Next, we try it by calling mergeDeep with 2 objects.

And we should see that merged is:

{
  "a": 1,
  "b": {
    "c": 123
  }
}

Lodash merge Method

If we don’t want to write our own function, then we can use the Lodash merge method to merge objects.

For instance, we can write:

const merged = _.merge({
  a: 1
}, {
  b: {
    c: 123
  }
});

And we get the same value for merged .

Conclusion

We can deep merge JavaScript objects with our own JavaScript function or the Lodash merge method.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *