Merge Two Objects in JavaScript: Practical Guide
Learn practical methods to merge two objects in JavaScript, including shallow and deep merges, spread syntax, Object.assign, and handling nested structures with clear examples, performance notes, and best practices for immutability.
To merge two objects in JavaScript, use the spread syntax: const merged = {...obj1, ...obj2}. This shallow merge copies top‑level properties, with obj2 taking precedence on overlapping keys. For nested objects, you’ll need a deep merge strategy via a recursive function or a library like lodash.merge.
Core concepts: shallow vs deep merge
Merging objects in JavaScript is a common task when combining data from different sources. At its core, a shallow merge creates a new object and copies over properties from the source objects. If a property value is itself an object, the reference is copied, not the nested structure merged. This means nested changes in one source can affect the other if you mutate objects after merging.
const a = { x: 1, y: { m: 1 } };
const b = { y: { n: 2 }, z: 3 };
const shallowMerged = { ...a, ...b };
console.log(shallowMerged);
// { x: 1, y: { n: 2 }, z: 3 }When you mutate shallowMerged.y, you may inadvertently mutate a or b.y because they reference the same object. A deep merge creates or merges nested objects, ensuring independent copies of nested data.
function isObject(v) { return v && typeof v === 'object' && !Array.isArray(v); }
function deepMerge(target, source) {
for (const key in source) {
if (isObject(source[key]) && isObject(target[key])) {
deepMerge(target[key], source[key]);
} else {
target[key] = source[key];
}
}
return target;
}
const t = { a: { b: 1 }, c: 2 };
const s = { a: { d: 3 }, e: 4 };
console.log(deepMerge({ ...t }, s));
// { a: { d: 3 }, c: 2, e: 4 }descriptionBlockOpenTagRequiredUnderlinePositionForCopyingStyleNoteAndMoreExplanationAndPotentialHTMLTagsUsed
tipKeyShortNoteNoteNoop
Steps
Estimated time: 20-40 minutes
- 1
Define base objects
Create two source objects that you want to merge. Decide which properties should take precedence in case of key overlaps. For nested data, plan whether you want to deep-merge or replace.
Tip: Draft a small example to reason about key conflicts before coding the merge. - 2
Choose a merge strategy
If you only need a shallow merge, spread or Object.assign suffices. For nested objects, prepare a deep merge function or a library utility.
Tip: Document the expected shape of merged data to prevent surprises. - 3
Implement shallow merge
Use spread syntax to merge top-level properties. This creates a new object and preserves immutability for the top level.
Tip: Remember that nested objects are still shared by reference. - 4
Implement deep merge
Add a recursive function to merge nested objects without overwriting the entire nested structure.
Tip: Test with deeply nested examples to ensure correct behavior. - 5
Validate results
Log the merged object and compare with expected results. Check for property order, key overwrites, and nested merges.
Tip: Use JSON.stringify for readable diffs in logs. - 6
Handle edge cases
Consider undefined values, nulls, arrays, and non-plain objects. Decide whether to merge arrays or replace them.
Tip: Edge cases often reveal hidden assumptions in your merge logic.
Prerequisites
Required
- JavaScript runtime environment (Node.js 14+ or a modern browser)Required
- Understanding of ES6 spread syntax and Object.assignRequired
- Required
- NPM or Yarn for package managementRequired
Optional
- Optional: example data to practice merging (flat and nested objects)Optional
Keyboard Shortcuts
| Action | Shortcut |
|---|---|
| Copy | Ctrl+C |
| Paste | Ctrl+V |
| Undo | Ctrl+Z |
| Format document | Ctrl+⇧+F |
| Find | Ctrl+F |
Questions & Answers
What is the difference between shallow merge and deep merge in JavaScript?
A shallow merge copies top-level properties and uses existing nested objects by reference. A deep merge recursively merges nested objects, creating independent copies of nested data. Understanding this distinction helps prevent unintended mutations and data loss.
Shallow merges copy properties at the top level, while deep merges handle nested objects by merging their content step by step.
How do you merge two objects with overlapping keys?
When keys clash, the value from the source object that appears later in the merge order wins. Using spread syntax, const merged = { ...a, ...b } applies b’s values to any overlapping keys.
If two objects share a key, the value from the later object wins in the merged result.
Can you merge objects that contain arrays or functions?
Arrays can be concatenated or replaced depending on the merge strategy. Functions are treated as values and will be overwritten if keys collide or copied by reference in shallow merges.
Arrays can be merged by concatenating, while functions are copied as values during the merge.
Is Object.assign deprecated in favor of spread syntax?
Object.assign is not deprecated and remains valid, but the spread operator is often preferred for readability and conciseness in modern code. For deep merges, neither handles nested merges automatically.
You can still use Object.assign, but many developers prefer spread syntax for its simplicity.
How can I ignore undefined values during a merge?
You can filter keys or implement a custom merge that skips undefined values. Pure spread or Object.assign will copy undefined values if present, so you may need a guard when constructing the merged object.
If a key has undefined, you might want to skip copying it to keep your data clean.
What to Remember
- Use spread or Object.assign for shallow merges
- Implement a deep merge for nested structures
- Be mindful of object references to avoid unintended mutations
- Test with nested data and edge cases to ensure robustness
