How to merge properties of two javascript objects

Posted on

To merge properties of two JavaScript objects, you can use various methods depending on your requirements and the structure of the objects. Merging objects involves combining their properties into a single object, ensuring that overlapping properties are handled according to your specific logic, such as overwriting or merging nested objects. This process is useful for scenarios like combining configurations, merging data structures, or updating state objects in JavaScript applications.

Using Object.assign()

Basic merging: The Object.assign() method is a straightforward way to merge properties from multiple source objects into a target object.

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

const merged = Object.assign({}, obj1, obj2);
console.log(merged); // Output: { a: 1, b: 3, c: 4 }

In this example, Object.assign({}, obj1, obj2) merges obj1 and obj2 into an empty object {}, ensuring that properties from obj2 overwrite those from obj1 where keys overlap (b in this case).

Deep merging: Object.assign() performs a shallow copy, so nested objects are copied by reference. For deep merging, consider using libraries like Lodash or implementing custom logic.

Spread Operator (…)

ES6 Spread Operator: The spread syntax (...) provides a concise way to merge properties of objects, especially useful for creating shallow copies and merging.

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

const merged = { ...obj1, ...obj2 };
console.log(merged); // Output: { a: 1, b: 3, c: 4 }

Here, { ...obj1, ...obj2 } creates a new object with properties from both obj1 and obj2. Like Object.assign(), the spread operator prioritizes properties from obj2 when keys overlap.

Immutable merge: Using spread syntax ensures immutability by creating a new object without modifying the original objects (obj1 and obj2).

Custom Merge Functions

Handling nested objects: For complex objects with nested structures, custom merge functions offer flexibility to define specific merging behaviors, such as deep merging nested objects.

function mergeObjects(target, ...sources) {
    sources.forEach(source => {
        for (const key in source) {
            if (typeof source[key] === 'object' && source[key] !== null) {
                if (!target[key]) Object.assign(target, { [key]: {} });
                mergeObjects(target[key], source[key]);
            } else {
                Object.assign(target, { [key]: source[key] });
            }
        }
    });
    return target;
}

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

const merged = mergeObjects({}, obj1, obj2);
console.log(merged); // Output: { a: 1, b: { c: 2, d: 3 }, e: 4 }

In this example, mergeObjects() recursively merges obj1 and obj2, handling nested objects by merging their properties accordingly.

Lodash Library

Using Lodash merge: Lodash provides a robust merge() function for deep merging objects, handling edge cases like arrays, circular references, and prototype properties.

const _ = require('lodash');

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

const merged = _.merge({}, obj1, obj2);
console.log(merged); // Output: { a: 1, b: { c: 2, d: 3 }, e: 4 }

Lodash’s _.merge() function is versatile for merging complex objects and ensuring consistent handling of various data structures.

Considerations and Performance

Key conflicts: When merging objects, consider how to handle conflicts where keys are shared between objects. Default behaviors like those in Object.assign() prioritize later sources (right-most in spread operator).

Performance: Methods like Object.assign() and the spread operator (...) are efficient for most use cases. For extremely large or deeply nested objects, benchmarking or optimizing custom merge functions may be necessary.

Summary

Merging properties of JavaScript objects involves combining their key-value pairs into a single object, accommodating different structures and requirements. Whether using built-in methods like Object.assign() and spread syntax (...), implementing custom merge functions for specific behaviors, or leveraging libraries such as Lodash for complex merges, JavaScript offers versatile approaches to handle object merging tasks efficiently. By understanding these methods, considering edge cases like nested objects or key conflicts, and optimizing for performance when needed, developers can effectively manage and manipulate object data structures in JavaScript applications, ensuring clarity, maintainability, and functionality in their codebases.

Was this helpful?

Thanks for your feedback!