AskHandle

AskHandle Blog

How can I deeply merge two objects in JavaScript?

May 16, 2025Ben Larson3 min read

How can I deeply merge two objects in JavaScript?

When working with JavaScript, especially in projects involving configurations or complex data structures, you often need to combine two objects into one. Sometimes, a simple merge that overwires properties at the top level isn’t enough. Instead, you need to merge objects deeply, combining nested objects as well. This is a common question during technical interviews because deep merging involves understanding recursion, object handling, and sometimes third-party libraries.

A shallow merge using Object.assign() or the spread operator ({...obj1, ...obj2}) copies only the first level of an object. For example:

javascript
1const obj1 = { a: 1, b: { c: 2 } };
2const obj2 = { b: { d: 3 } };
3
4const merged = { ...obj1, ...obj2 }; // { a: 1, b: { d: 3 } }

In this case, the b property from obj2 overwrites the b property in obj1. Notice how the nested object b is replaced entirely, not merged.

To perform a deep merge, you need to recursively traverse both objects and merge their properties. Here’s a simple implementation of a deep merge function:

javascript
1function deepMerge(target, source) {
2  // Loop through each property in the source object
3  for (const key in source) {
4    // Check if the property exists in source
5    if (source.hasOwnProperty(key)) {
6      const sourceValue = source[key];
7      const targetValue = target[key];
8
9      // If both values are objects, recurse
10      if (
11        sourceValue && typeof sourceValue === 'object' &&
12        targetValue && typeof targetValue === 'object'
13      ) {
14        deepMerge(targetValue, sourceValue);
15      } else {
16        // Otherwise, assign the source value to target
17        target[key] = sourceValue;
18      }
19    }
20  }
21  return target;
22}

You can use this function like this:

javascript
1const obj1 = { a: 1, b: { c: 2 } };
2const obj2 = { b: { d: 3 }, e: 4 };
3
4const mergedObject = deepMerge({ ...obj1 }, obj2);
5console.log(mergedObject);
6// Output: { a: 1, b: { c: 2, d: 3 }, e: 4 }

It’s important to note that this implementation modifies the first object you pass to it, so if you want to keep your original objects unchanged, you should pass a copy of the first object, like in the example above ({ ...obj1 }).

There are also popular utility libraries like Lodash that offer a _.merge() method, which performs deep merging easily:

javascript
1const _ = require('lodash');
2
3const obj1 = { a: 1, b: { c: 2 } };
4const obj2 = { b: { d: 3 }, e: 4 };
5
6const mergedObject = _.merge({}, obj1, obj2);
7console.log(mergedObject);
8// Output: { a: 1, b: { c: 2, d: 3 }, e: 4 }

Using such libraries can simplify your code and improve reliability, especially for more complex cases.