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.