JavaScript Merge Objects: Spread, Object.assign, and Deep Merge

Deepak Prasad
Short on time?Beta Get the gist of this 3-minute read in seconds, then ask follow-up questions

You merge plain objects in JavaScript whenever you need one configuration object built from defaults, feature flags, and user input. The two mainstream shallow merges are object spread ({ ...a, ...b }) and Object.assign({}, a, b)—later keys win when names collide. Nested objects are still shared by reference after a shallow merge; when you truly need tree-shaped copies, reach for structured cloning or a dedicated deep-merge utility, and contrast this with how JavaScript object literals and the spread operator behave in isolation.

Environment: Node.js v20.18.2. After each runnable snippet, the following paragraph states the expected console output (order and values).


Method 1: Merge Objects with Spread Syntax

javascript
const user = { name: "Ana", role: "dev" };
const update = { role: "admin", active: true };

const merged = { ...user, ...update };

console.log(merged);
Output

You should see one line logging { name: 'Ana', role: 'admin', active: true }.

When keys conflict, the later object wins. Here, role: "admin" overwrites role: "dev".


Method 2: Merge Objects with Object.assign()

javascript
const target = { a: 1 };
const assigned = Object.assign(target, { b: 2 });

console.log(target === assigned);
Output

You should see one line logging true.

Object.assign() mutates the target object. Use an empty target when you want a new object:

javascript
const merged = Object.assign({}, objectA, objectB);
Output

Method 3: Understand Shallow Merge Behavior

Spread and Object.assign() are shallow. Nested objects are replaced, not deeply combined.

javascript
const a = { user: { name: "Ana" } };
const b = { user: { role: "admin" } };

console.log({ ...a, ...b });
Output

You should see one line logging { user: { role: 'admin' } }.

The nested user.name value is not preserved because the whole user object is replaced.


Method 4: Clone Before Merging Nested Data

For structured-cloneable data, structuredClone() can make a deep copy before you merge or modify nested data.

javascript
const copy = structuredClone({ a: { b: 1 } });

console.log(copy.a.b);
Output

You should see one line logging 1.

For a true recursive deep merge, write domain-specific logic or use a tested library, because merge rules for arrays, dates, maps, and class instances vary by project.


Common Questions About Merging Objects in JavaScript

How do I merge two objects in JavaScript?

Use { ...a, ...b } for a new shallow merged object, or Object.assign({}, a, b).

Which object wins when keys conflict?

The later object wins. In { ...a, ...b }, properties from b overwrite matching properties from a.

Is object spread a deep merge?

No. Object spread is shallow. Nested objects are copied by reference or replaced at the top-level property.


Summary

To merge objects in JavaScript, use spread syntax for the most readable shallow merge and Object.assign() when you specifically want assignment-style behavior. Both methods overwrite earlier keys with later keys and both are shallow, so nested objects need separate handling. Use structuredClone() when you need to copy structured-cloneable nested data before modifying it, and use a deliberate deep merge function or library when nested merge rules matter.


Official Documentation

Finished reading?Beta Get the key takeaways in seconds, then ask follow-up questions
Olorunfemi Akinlua

Boasting over five years of experience in JavaScript, specializing in technical content writing and UX design. With a keen focus on programming languages, he crafts compelling content and designs user-friendly interfaces to enhance digital experiences across various domains.

  • JavaScript
  • Web Design