Deep Merge Two Objects in JavaScript



In JavaScript, a deep merge of two objects means creating a new object by combining properties recursively, and adding nested objects. Unlike in a simple merge, it ensures that no properties are lost during the merge, which replaces the top-level properties. In this article, we will look at several ways of performing a deep merge of two objects, with code and explanations.

Approaches to Deep Merge

Manual Recursive Function

A custom function provides complete control over how the merge operates.

Example

function deepMerge(obj1, obj2) {
    const result = { ...obj1 }; // Start with a shallow copy of obj1

    for (const key in obj2) {
        if (obj2[key] && typeof obj2[key] === "object" && !Array.isArray(obj2[key])) {
            result[key] = deepMerge(result[key] || {}, obj2[key]);
        } else {
            result[key] = obj2[key];
        }
    }

    return result;
}

// Example usage
const obj1 = { name: "Pankaj", details: { age: 21, skills: ["JavaScript"] } };
const obj2 = { details: { age: 22, location: "India" }, hobbies: ["Coding"] };

const merged = deepMerge(obj1, obj2);
console.log(merged);

Output

{
  name: "Pankaj",
  details: { age: 22, skills: ["JavaScript"], location: "India" },
  hobbies: ["Coding"]
}

Using Lodash's merge Method

Lodash is a popular utility library for JavaScript. Its merge method makes it easy to merge objects deep.

Example

const _ = require('lodash');

const obj1 = { name: "Pankaj", details: { age: 21, skills: ["JavaScript"] } };
const obj2 = { details: { age: 22, location: "India" }, hobbies: ["Coding"] };

const merged = _.merge({}, obj1, obj2);
console.log(merged);

Output

{
  name: "Pankaj",
  details: { age: 22, skills: ["JavaScript"], location: "India" },
  hobbies: ["Coding"]
}

Using the Spread Operator with Recursion

The spread operator (...) can be combined with recursion for deep merging.

Example

function deepMerge(obj1, obj2) {
    return {
        ...obj1,
        ...Object.keys(obj2).reduce((acc, key) => {
            acc[key] = 
                obj1[key] && typeof obj2[key] === "object" && !Array.isArray(obj2[key])
                ? deepMerge(obj1[key], obj2[key])
                : obj2[key];
            return acc;
        }, {})
    };
}

// Example usage
const obj1 = { name: "Pankaj", details: { age: 21, skills: ["JavaScript"] } };
const obj2 = { details: { age: 22, location: "India" }, hobbies: ["Coding"] };

const merged = deepMerge(obj1, obj2);
console.log(merged);

Output

{
  name: "Pankaj",
  details: { age: 22, skills: ["JavaScript"], location: "India" },
  hobbies: ["Coding"]
}

Using Object.assign with Recursion

Object.assign can be used for merging but it needs recursion for deep merges.

Example

function deepMerge(obj1, obj2) {
    const result = Object.assign({}, obj1);

    for (const key in obj2) {
        if (obj2[key] && typeof obj2[key] === "object" && !Array.isArray(obj2[key])) {
            result[key] = deepMerge(result[key] || {}, obj2[key]);
        } else {
            result[key] = obj2[key];
        }
    }

    return result;
}

// Example usage
const obj1 = { name: "Pankaj", details: { age: 21, skills: ["JavaScript"] } };
const obj2 = { details: { age: 22, location: "India" }, hobbies: ["Coding"] };

const merged = deepMerge(obj1, obj2);
console.log(merged);

Output

{
  name: "Pankaj",
  details: { age: 22, skills: ["JavaScript"], location: "India" },
  hobbies: ["Coding"]
}
Updated on: 2025-01-06T10:42:06+05:30

817 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements