Objects and destructuring

Property shorthand, spread merging, optional chaining, and copying objects without the reference traps.

Short modern syntax

const id = 7, active = true;
const user = { id, active };           // property shorthand
const user2 = { id, role: 'admin', login() { return this.id; } };

const { id: userId, role = 'guest' } = user2;  // rename + default
const copy = { ...user2, role: 'owner' };      // spread override
  • Computed keys: { [key]: value }.
  • Optional chaining: user?.profile?.email β€” short-circuits instead of throwing.
  • Nullish coalescing: x ?? 'default' β€” unlike || it keeps 0 and ''.

References and copies

Objects are copied by reference: assigning one does not clone it, so both variables point at the same data.

const a = { tags: ['x'] };
const b = a;
b.tags.push('y');
console.log(a.tags); // ['x','y'] - same object

const shallow = { ...a };              // top level copied only
const deep = structuredClone(a);       // true deep copy (modern runtimes)
⚠️
Spread is a shallow copy β€” nested objects still share references. Use structuredClone for a genuine deep copy (it handles Dates, Maps and Sets; unlike JSON.parse(JSON.stringify()), which silently mangles them).

Object vs Map

UseWhen
ObjectFixed known shape, JSON interchange, simple records
MapDynamic keys, frequent add/remove, non-string keys, insertion order matters
const m = new Map();
m.set(user, 'cached');   // any key type
m.size;                  // no Object.keys length dance
for (const [k, v] of m) console.log(k, v);

FAQ

How do I safely read a nested value?
Optional chaining plus nullish coalescing: cfg?.db?.host ?? 'localhost'.
Why does mutating the copy change the original?
You copied the reference, not the data. Use spread for one level or structuredClone for the whole tree.

JSON basics JavaScript basics

Last refreshed 2026-09-17.