Are you a beginner exploring the exciting world of JavaScript? Ever wondered, “How to merge objects in JavaScript?” Well, you’re in the right place! Merging objects is a fundamental concept that every budding developer needs to grasp. Whether you’re building simple web applications or complex systems, understanding how to seamlessly combine objects can save you loads of time and effort. In this blog, we’ll break down this essential concept into easy-to-digest sections with practical examples and insights. So, let’s dive in and simplify ‘How to Merge Objects in JavaScript?’ together! Keep reading to unlock the potential of your coding skills.
Methods to Merge Objects in JavaScript
JavaScript provides multiple ways to merge objects, with the most common methods being the spread operator (...
) and Object.assign()
.
1. Using the Spread Operator (...
)
Syntax and Basic Usage:
The spread operator (...
) allows you to merge objects in a clean and concise manner.
const obj1 = { name: "Alice", age: 25 }; const obj2 = { city: "New York", country: "USA" }; const mergedObj = { ...obj1, ...obj2 }; console.log(mergedObj); // Output: { name: 'Alice', age: 25, city: 'New York', country: 'USA' }
Key Points:
- The spread operator creates a shallow copy of objects.
- If objects have duplicate keys, the last object’s value overwrites the previous ones.
2. Using Object.assign()
Syntax and Basic Usage:
The Object.assign()
method merges multiple objects into a target object.
const obj1 = { name: "Alice", age: 25 }; const obj2 = { city: "New York", country: "USA" }; const mergedObj = Object.assign({}, obj1, obj2); console.log(mergedObj); // Output: { name: 'Alice', age: 25, city: 'New York', country: 'USA' }
Merging Multiple Objects:
You can merge multiple objects using Object.assign()
.
const obj3 = { profession: "Developer" }; const finalObj = Object.assign({}, obj1, obj2, obj3); console.log(finalObj); // Output: { name: 'Alice', age: 25, city: 'New York', country: 'USA', profession: 'Developer' }
Key Points:
Object.assign()
modifies the first argument (target object).- To avoid modifying existing objects, always pass an empty object (
{}
) as the first argument. - Like the spread operator, it performs shallow merging (does not merge nested objects deeply).
Both methods are widely used, but the spread operator is preferred for its simplicity and readability.
Shallow vs. Deep Merging in JavaScript
When merging objects, it’s essential to understand the difference between shallow merging and deep merging, especially when dealing with nested objects.
Shallow Merging
What is a Shallow Copy?
A shallow copy creates a new object but only copies top-level properties. If the object contains nested objects (references), those references are shared, meaning modifications to nested properties affect the original object.
Example: Shallow Merge Using Spread Operator (...
)
const obj1 = { name: "Alice", details: { age: 25, city: "New York" } }; const obj2 = { country: "USA" }; const shallowMerged = { ...obj1, ...obj2 }; console.log(shallowMerged); // Output: { name: 'Alice', details: { age: 25, city: 'New York' }, country: 'USA' } // Modifying the nested object in the merged object shallowMerged.details.city = "Los Angeles"; console.log(obj1.details.city); // Output: "Los Angeles" (also changed in obj1)
Implications of Shallow Merging for Nested Objects:
- Only top-level properties are copied.
- Nested objects remain referenced, so changes affect both the original and merged objects.
- Suitable for flat objects but problematic for deeply nested structures.
Deep Merging
What is a Deep Copy?
A deep copy creates a completely independent copy of all properties, including nested objects, ensuring changes to the new object do not affect the original.
Techniques to Perform Deep Merging
1. Using JSON.parse(JSON.stringify())
(Simple Deep Copy)
This method works for objects without functions or special types (e.g., Date
, RegExp
).
const obj1 = { name: "Alice", details: { age: 25, city: "New York" } }; const obj2 = { country: "USA" }; const deepMerged = JSON.parse(JSON.stringify({ ...obj1, ...obj2 })); deepMerged.details.city = "Los Angeles"; console.log(obj1.details.city); // Output: "New York" (unchanged)
Limitations:
- Cannot handle functions,
Date
,Map
,Set
, or circular references.
2. Using a Custom Recursive Function
For a more flexible deep merge, a recursive function is needed.
function deepMerge(target, source) { for (let key in source) { if (source[key] instanceof Object && key in target) { target[key] = deepMerge(target[key], source[key]); } else { target[key] = source[key]; } } return target; } const obj1 = { name: "Alice", details: { age: 25, city: "New York" } }; const obj2 = { details: { city: "Los Angeles" }, country: "USA" }; const deepMerged = deepMerge({}, obj1); deepMerge(deepMerged, obj2); console.log(deepMerged); // Output: { name: 'Alice', details: { age: 25, city: 'Los Angeles' }, country: 'USA' }
3. Using Lodash (_.merge
)
Lodash provides a robust deep merge function.
const _ = require("lodash"); const obj1 = { name: "Alice", details: { age: 25, city: "New York" } }; const obj2 = { details: { city: "Los Angeles" }, country: "USA" }; const deepMerged = _.merge({}, obj1, obj2); console.log(deepMerged); // Output: { name: 'Alice', details: { age: 25, city: 'Los Angeles' }, country: 'USA' }
Why Use Lodash?
- Handles nested objects and arrays efficiently.
- Supports circular references and special types like
Date
.
Summary: Choosing the Right Merge Method
Merge Type | Method | Best for |
---|---|---|
Shallow Merge | Spread (... ), Object.assign() | Simple objects, no nested data |
Deep Merge (Basic) | JSON.parse(JSON.stringify()) | Nested objects without functions or special types |
Deep Merge (Custom) | Recursive function | Full control over merging logic |
Deep Merge (Lodash) | _.merge() | Complex objects with deep nesting |
For simple objects, the spread operator is sufficient, but for deeply nested objects, custom recursive functions or Lodash should be used.
Practical Examples of Merging Objects in JavaScript
Merging objects can involve handling overlapping properties and nested objects. Below are examples demonstrating both cases.
1. Merging Objects with Overlapping Properties
When two objects have the same property, the value from the second object overwrites the first.
Example: Using the Spread Operator (...
)
const obj1 = { name: "Alice", age: 25 }; const obj2 = { age: 30, city: "New York" }; const mergedObj = { ...obj1, ...obj2 }; console.log(mergedObj); // Output: { name: 'Alice', age: 30, city: 'New York' }
Key Takeaways:
- The
age
property inobj2
replacesage
inobj1
. - New properties (
city
) are added to the merged object.
2. Handling Nested Objects During Merge Operations
Issue with Shallow Merging
If objects have nested properties, a shallow merge does not merge deeply—it replaces the entire nested object instead.
const obj1 = { name: "Alice", details: { age: 25, city: "New York" } }; const obj2 = { details: { city: "Los Angeles" } }; const shallowMerged = { ...obj1, ...obj2 }; console.log(shallowMerged); // Output: { name: 'Alice', details: { city: 'Los Angeles' } } ❌ (age is lost!)
Problem:
- The entire
details
object fromobj1
is replaced instead of merging properties inside it.
Deep Merging Using Lodash (_.merge()
)
Lodash provides a deep merging function to properly combine nested objects.
const _ = require("lodash"); const obj1 = { name: "Alice", details: { age: 25, city: "New York" } }; const obj2 = { details: { city: "Los Angeles" } }; const deepMerged = _.merge({}, obj1, obj2); console.log(deepMerged); // Output: { name: 'Alice', details: { age: 25, city: 'Los Angeles' } } ✅ (age is retained)
Custom Deep Merge Function (Without Lodash)
For projects without Lodash, you can use a recursive function to deep merge objects.
function deepMerge(target, source) { for (let key in source) { if (source[key] instanceof Object && key in target) { target[key] = deepMerge(target[key], source[key]); } else { target[key] = source[key]; } } return target; } const obj1 = { name: "Alice", details: { age: 25, city: "New York" } }; const obj2 = { details: { city: "Los Angeles" } }; const deepMerged = deepMerge({}, obj1); deepMerge(deepMerged, obj2); console.log(deepMerged); // Output: { name: 'Alice', details: { age: 25, city: 'Los Angeles' } }
Summary: Choosing the Right Merge Method
Merge Type | Method | Best for |
---|---|---|
Shallow Merge | Spread (... ), Object.assign() | Simple objects, no nested data |
Deep Merge (Basic) | JSON.parse(JSON.stringify()) | Nested objects without functions or special types |
Deep Merge (Custom) | Recursive function | Full control over merging logic |
Deep Merge (Lodash) | _.merge() | Complex objects with deep nesting |
For basic objects, the spread operator works fine. However, for nested objects, deep merging methods (Lodash or recursive functions) are required.
Our AI-powered js online compiler lets users instantly write, run, and test code, making learning JavaScript seamless. With AI assistance, coding becomes intuitive and efficient, helping users understand concepts faster while providing a friendly environment for beginners to experiment and grow.
Common Pitfalls and Considerations When Merging Objects in JavaScript
Merging objects in JavaScript seems straightforward, but it can lead to unexpected issues. Below are some common pitfalls and best practices to handle them effectively.
1. Overwriting Properties with the Same Key
When two objects have the same property key, the value from the second object overwrites the first.
Example: Unexpected Overwrite
const obj1 = { name: "Alice", age: 25 }; const obj2 = { age: 30, city: "New York" }; const merged = { ...obj1, ...obj2 }; console.log(merged); // Output: { name: 'Alice', age: 30, city: 'New York' } ❌ (age is overwritten)
Solution: Prevent Overwrites by Using Unique Keys
If you want to keep both values, rename conflicting keys before merging:
const obj2 = { ageUpdated: 30, city: "New York" }; const merged = { ...obj1, ...obj2 }; console.log(merged); // Output: { name: 'Alice', age: 25, ageUpdated: 30, city: 'New York' } ✅ (both values retained)
2. Performance Considerations for Large Objects
Merging large objects, especially deeply nested ones, can impact performance and memory usage.
Issue: High Memory Usage in Large Objects
const largeObj1 = { data: new Array(1000000).fill("A") }; const largeObj2 = { data: new Array(1000000).fill("B") }; const merged = { ...largeObj1, ...largeObj2 }; console.log(merged.data.length); // 1000000 ❌ (data in obj1 is lost)
Solution: Use Efficient Merging Strategies
- Avoid unnecessary deep copies when merging large datasets.
- Use streaming or batched merging for very large objects.
- Use Object.assign() over spread operator when memory efficiency is a concern.
const merged = Object.assign({}, largeObj1, largeObj2);
3. Ensuring Immutability During Merge Operations
Mutating original objects can lead to unexpected bugs, especially in functional programming or React state updates.
Issue: Directly Modifying the Original Object
const obj1 = { name: "Alice" }; const obj2 = { age: 30 }; Object.assign(obj1, obj2); // Mutates obj1! console.log(obj1); // Output: { name: 'Alice', age: 30 } ❌ (obj1 is modified)
Solution: Use Immutable Merging Techniques
To preserve immutability, always create a new object instead of modifying the existing one.
const merged = Object.assign({}, obj1, obj2); console.log(obj1); // Output: { name: 'Alice' } ✅ (obj1 remains unchanged)
Alternatively, with the spread operator:
const merged = { ...obj1, ...obj2 };
For deep merges, libraries like Lodash ensure immutability:
const _ = require("lodash"); const merged = _.merge({}, obj1, obj2);
Summary: Best Practices for Safe Object Merging
Pitfall | Solution |
---|---|
Overwriting properties | Rename keys to avoid conflicts |
Performance issues | Avoid unnecessary deep copies, use batch processing |
Mutability risks | Always merge into a new object to prevent side effects |
By following these best practices, you can merge objects safely, efficiently, and without unintended side effects.
Conclusion
Understanding how to merge objects in JavaScript empowers you to manage data effectively, a crucial skill in modern coding. For more insights and tutorials on JavaScript and other programming languages, visit Newtum. Start your coding journey today and continue exploring new challenges!
Edited and Compiled by
This blog was compiled and edited by Rasika Deshpande, who has over 4 years of experience in content creation. She’s passionate about helping beginners understand technical topics in a more interactive way.