Best Ways to Merge JavaScript Nested Objects: A Step-by-Step Guide

by

Merging objects is a common task in JavaScript, especially when dealing with nested objects. Whether you’re handling configurations, state management, or combining data from different sources, knowing how to merge nested objects efficiently is crucial. In this guide, we’ll explore the best methods to merge JavaScript nested objects step by step.

Table of Contents

  1. Understanding Nested Objects
  2. Using the Spread Operator
  3. Using Object.assign()
  4. Deep Merging with Recursion
  5. Using Libraries like Lodash
  6. Practical Examples
  7. Conclusion
  8. Frequently Asked Questions

Understanding Nested Objects

Before diving into merging techniques, it’s essential to understand what nested objects are. A nested object is an object that contains another object as a property.

javascriptCopy codeconst obj1 = {
  name: 'John',
  address: {
    city: 'New York',
    zip: 10001
  }
};

In the example above, address is a nested object within obj1.

Using the Spread Operator

The spread operator (...) is a concise way to merge objects. However, it’s important to note that it performs a shallow merge.

javascriptCopy codeconst obj1 = { a: 1, b: { c: 2 } };
const obj2 = { d: 3 };

const mergedObj = { ...obj1, ...obj2 };

console.log(mergedObj);
// Output: { a: 1, b: { c: 2 }, d: 3 }

Limitations

When merging nested objects, the spread operator doesn’t merge the nested properties. Instead, it overwrites them.

javascriptCopy codeconst obj1 = { a: 1, b: { c: 2 } };
const obj2 = { b: { d: 4 } };

const mergedObj = { ...obj1, ...obj2 };

console.log(mergedObj);
// Output: { a:1, b: { d: 4 } }

In this case, the b property from obj1 is overwritten by the b property from obj2.

Using Object.assign()

Object.assign() is another method to merge objects. Like the spread operator, it performs a shallow merge.

javascriptCopy codeconst obj1 = { a: 1, b: { c: 2 } };
const obj2 = { d: 3 };

const mergedObj = Object.assign({}, obj1, obj2);

console.log(mergedObj);
// Output: { a: 1, b: { c: 2 }, d: 3 }

Limitations

Object.assign() has the same limitations as the spread operator when it comes to nested objects.

javascriptCopy codeconst obj1 = { a: 1, b: { c: 2 } };
const obj2 = { b: { d: 4 } };

const mergedObj = Object.assign({}, obj1, obj2);

console.log(mergedObj);
// Output: { a:1, b: { d: 4 } }

The nested b object from obj1 is overwritten by the b object from obj2.

Deep Merging with Recursion

To merge nested objects properly, you need to perform a deep merge. One way to achieve this is by using recursion.

javascriptCopy codefunction mergeDeep(target, source) {
  const output = Object.assign({}, target);
  if (isObject(target) && isObject(source)) {
    Object.keys(source).forEach(key => {
      if (isObject(source[key])) {
        if (!(key in target)) Object.assign(output, { [key]: source[key] });
        else output[key] = mergeDeep(target[key], source[key]);
      } else {
        Object.assign(output, { [key]: source[key] });
      }
    });
  }
  return output;
}

function isObject(obj) {
  return obj && typeof obj === 'object';
}

const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { b: { d: 4 } };

const mergedObj = mergeDeep(obj1, obj2);

console.log(mergedObj);
// Output: { a: 1, b: { c: 2, d: 4 } }

Explanation

  • mergeDeep Function: Recursively merges properties of two objects.
  • isObject Helper Function: Checks if a value is an object.
  • Process:
    • Iterate over source keys.
    • If the value is an object, recursively merge.
    • Otherwise, assign the value to the output object.

Using Libraries like Lodash

Libraries like Lodash provide utility functions for deep merging objects.

javascriptCopy codeconst _ = require('lodash');

const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { b: { d: 4 } };

const mergedObj = _.merge({}, obj1, obj2);

console.log(mergedObj);
// Output: { a: 1, b: { c: 2, d: 4 } }

Advantages

  • Handles Complex Structures: Efficiently merges deeply nested objects.
  • Well-Tested: Reduces bugs and edge cases.
  • Convenience: Saves time by using pre-built functions.

Practical Examples

Merging User Settings

Imagine you have default settings and user-specific settings that you want to merge.

javascriptCopy codeconst defaultSettings = {
  theme: 'light',
  layout: {
    sidebar: true,
    footer: true
  }
};

const userSettings = {
  theme: 'dark',
  layout: {
    footer: false
  }
};

const finalSettings = mergeDeep(defaultSettings, userSettings);

console.log(finalSettings);
// Output: { theme: 'dark', layout: { sidebar: true, footer: false } }

Combining API Responses

When combining data from multiple API responses:

javascriptCopy codeconst apiResponse1 = {
  user: {
    name: 'Alice',
    contacts: {
      email: '[email protected]'
    }
  }
};

const apiResponse2 = {
  user: {
    contacts: {
      phone: '123-456-7890'
    }
  }
};

const combinedData = mergeDeep(apiResponse1, apiResponse2);

console.log(combinedData);
// Output: { user: { name: 'Alice', contacts: { email: '[email protected]', phone: '123-456-7890' } } }

Conclusion

Merging nested objects in JavaScript can be straightforward or complex, depending on your needs. For shallow merges, the spread operator and Object.assign() suffice. For deep merges, consider using recursive functions or trusted libraries like Lodash.

Frequently Asked Questions

What is the difference between shallow and deep merge?

  • Shallow Merge: Only merges the first level of properties. Nested objects are overwritten.
  • Deep Merge: Recursively merges nested objects, combining their properties.

Why should I use a library like Lodash?

Lodash’s merge function is optimized and handles various edge cases. It saves time and reduces potential bugs in your code.

Can I merge more than two objects?

Yes, both the spread operator and Object.assign() can merge multiple objects.

javascriptCopy codeconst mergedObj = { ...obj1, ...obj2, ...obj3 };

References

Feel free to share your thoughts or ask questions in the comments below!

all_in_one_marketing_tool