Hiprup

What is the difference between Object.assign() and spread for objects?

Both copy properties into a new object, with subtle differences.

  • Spread ({...obj}) — concise, creates a new object, the modern default.

  • Object.assign(target, ...sources) — copies into an existing target (mutates it) and returns it.

  • Setters — Object.assign triggers setters on the target; spread defines plain properties.

Both are shallow: nested objects are still shared by reference.

const defaults = { color: 'red', size: 'M', theme: 'light' };
const custom = { color: 'blue', weight: 5 };

// Spread — new object
const merged1 = { ...defaults, ...custom };
// { color: 'blue', size: 'M', theme: 'light', weight: 5 }

// Object.assign — modifies target
const merged2 = Object.assign({}, defaults, custom);
// Same result, but {} is modified and returned

// Key difference: assign modifies target
const target = { a: 1 };
Object.assign(target, { b: 2 }); // target is now { a: 1, b: 2 }

// Spread always creates new
const result = { ...target, c: 3 }; // New object, target unchanged

// Both are SHALLOW
const obj = { nested: { x: 1 } };
const copy = { ...obj };
copy.nested.x = 99;
console.log(obj.nested.x); // 99 — shared reference!

Spread creates a new object; Object.assign modifies the target. Both merge left-to-right (last wins for conflicts).

Both are SHALLOW — nested objects are shared references. For deep copy, use structuredClone.

Spread = always new object (preferred). Object.assign = modifies target. Both are SHALLOW (nested objects shared).

Last source wins for conflicts. For deep copy: structuredClone. Spread is cleaner and more common in modern JS.

What is the difference between Object.assign() and spread for objects? | Hiprup