Volume 2

Q127: Destructuring, Rest and Spread Semantics

Difficulty: SeniorFrequency: MediumAnswer time: 8-12 minutes

What Interviewers Want To Evaluate

This question checks whether you understand modern syntax beyond surface usage. Interviewers want array and object destructuring, defaults, renaming, rest properties, spread properties, shallow copy behavior, iterable spread, argument spread, and common footguns.

Senior answers should connect syntax to readability, immutable updates, API boundaries, and accidental reference sharing.

Short Interview Answer

Destructuring extracts values from arrays or objects into variables. Rest collects remaining values. Spread expands iterable values, arrays, objects, or arguments depending on context. Object and array spread are shallow, so nested objects are still shared. Defaults only apply when the extracted value is undefined, not when it is null. These tools improve readability when used clearly, but over-nested destructuring can make code harder to understand.

Detailed Interview Answer

Destructuring binds values from a structure.

const user = {
  id: "u1",
  name: "Asha",
};

const { id, name } = user;

This is equivalent to reading user.id and user.name, but it makes the required fields visible.

Object Destructuring

Object destructuring matches property names.

const { role } = user;

You can rename variables.

const { id: userId } = user;

The property is id; the local variable is userId.

Default Values

Defaults apply only when the value is undefined.

const { pageSize = 20 } = { pageSize: undefined };
console.log(pageSize); // 20

const { density = "comfortable" } = { density: null };
console.log(density); // null

This distinction matters when null is a deliberate API value.

Nested Destructuring

const {
  profile: { email },
} = user;

This is concise but can throw if profile is missing.

const email = user.profile?.email;

Optional chaining is often clearer for uncertain nested data.

Array Destructuring

Array destructuring uses position.

const [first, second] = items;

You can skip positions.

const [, secondItem] = items;

Use this sparingly because skipped positions can reduce readability.

Rest in Destructuring

Rest collects remaining properties or elements.

const { password, ...safeUser } = user;

This is useful for removing fields before passing data forward.

For arrays:

const [head, ...tail] = items;

Rest creates a new shallow container.

Object Spread

Object spread copies enumerable own properties into a new object.

const nextUser = {
  ...user,
  name: "Meera",
};

Later properties override earlier ones.

const result = {
  theme: "light",
  ...preferences,
};

preferences.theme wins if present.

Array Spread

Array spread expands iterable values.

const nextItems = [...items, newItem];

This creates a new array but does not deep clone elements.

Argument Spread

Spread can pass array values as arguments.

const max = Math.max(...numbers);

Be careful with extremely large arrays because spreading into arguments can hit engine limits.

Iterable Spread

Array spread works with iterables.

const values = [...new Set([1, 1, 2])];

Object spread does not use the iterable protocol. It copies object properties.

Shallow Copy Footgun

const copy = { ...state };
copy.user.name = "Meera";

This mutates the nested user object shared with state.

Spread is not a deep clone.

Common Mistakes

A common mistake is using deeply nested destructuring in function parameters.

function render({ user: { profile: { email } } }) {}

This makes missing data errors and parameter expectations harder to scan.

Prefer destructuring inside the function when validation or fallbacks are needed.

Senior Trade-Offs

Use destructuring to make dependencies clear. Avoid clever destructuring that hides defensive checks.

Use spread for shallow immutable updates, but switch to normalized data, helper functions, or structured cloning when ownership requires deeper copying.

Code or Design Example

function sanitizeUserForClient(user) {
  const { passwordHash, internalNotes, ...clientUser } = user;
  return clientUser;
}

This removes sensitive fields from a shallow object. Nested sensitive fields still need explicit handling.

Debugging Workflow

When destructuring or spread behaves unexpectedly:

check undefined vs null defaults
check missing nested objects
check property override order
check shallow reference sharing
check enumerable own properties only
check array position assumptions
check whether value is iterable

Interview Framing

Define destructuring, rest, and spread separately. Then mention defaults, shallow copy behavior, and override order.

Revision Notes

Destructuring extracts, rest collects, and spread expands or copies depending on context. Spread is shallow.

Key Takeaways

Modern syntax is best when it makes data shape clearer. If it hides validation or ownership, make the code more explicit.

Follow-Up Questions

  1. What does object destructuring do?
  2. How do you rename during destructuring?
  3. When do destructuring defaults apply?
  4. What does rest collect?
  5. What does object spread copy?
  6. Is spread a deep clone?
  7. How does array spread relate to iterables?
  8. What happens with property override order?
  9. Why can nested parameter destructuring be risky?
  10. When should destructuring be avoided?

How I Would Answer This In A Real Interview

I would explain that destructuring extracts, rest gathers remaining values, and spread expands or shallow-copies. Then I would call out defaults, object override order, iterable spread, and the important shallow-copy limitation.