Destructuring, spread, rest and defaults: modern syntax you read every day
Unpack objects and arrays, collect extra arguments, copy with spread, and know when default values run. With the traps interviewers ask about.
Comes up in: JavaScript, Recruiter screen
Learn#
Ravi reads an API response: const id = order.id; const name = order.user.name; const currency = order.currency || "INR";. Three lines, and a bug: a currency of "" becomes "INR".
Destructuring unpacks values from an object or array into variables, in one line. You can rename, set defaults and reach into nested parts.
const order = { id: 7, user: { name: "Asha" } };
const { id, user: { name: buyer }, currency = "INR" } = order;
const [first, , third = "none"] = ["a", "b"];
console.log(id, buyer, currency, first, third);Output (verified)
7 Asha INR a none
A default applies only when the value is undefined, not when it is "", 0 or null.
State
- arg = { id: 7, user: { name: 'Asha' } }
The function receives one object: the order.
Read the steps as text
- The function receives one object: the order.
- Destructuring pulls out id and renames user.name to buyer.
- currency is missing (undefined), so its default runs now, at call time.
A rest parameter, ...args, collects the remaining arguments into a real array.
Spread syntax does the opposite: it expands an array or object in place, as in Math.max(...nums) or { ...defaults, ...options }.
Predict#
Predict first
function f({ a } = {}) { return a } — what does f(null) do?
The default = {} replaces only undefined. null is passed through, and destructuring null throws a TypeError (“Cannot destructure property ‘a’ … as it is null”). It is tempting because null feels like “no value”, but defaults treat only undefined that way.
Interview angle#
Say it like this — about 30 seconds
“Destructuring unpacks objects and arrays into variables, with renaming, nesting and defaults. Defaults apply only for undefined and are evaluated at call time, every time. Rest parameters collect the remaining arguments into a real array. The old arguments object is array-like, has no array methods, and does not exist in arrow functions. Spread expands arrays or objects; object spread makes a shallow copy, so nested objects are still shared.”
Follow-up What is the difference between rest parameters and arguments?
arguments is array-like, holds every argument, and arrows do not have their own.Follow-up Does object spread make a deep copy?
Follow-up When is a default parameter evaluated?
f(x = []) gets a new array every call.Practice#
Guided
Write the four small functions with destructuring, rest, spread and defaults.
Done when
label()with no argument returns “guest (Pune)” instead of throwing.totalaccepts any number of prices, including none.withDefaultsnever changes the object it receives.firstAndRestuses array destructuring with a rest element.
Remember#
Try to answer each card before you open it. Then add them to your reviews.
When does a destructuring default apply?
Only when the value is undefined, not for null, 0 or empty string.
Rest parameter vs arguments: name two differences.
Rest is a real array of extra arguments; arrow functions have no arguments object.
Is { ...obj } a deep copy?
No. It is shallow; nested objects are shared.
What does this print?function f(x = []) { x.push(1); return x.length }\nconsole.log(f(), f())
function f(x = []) { x.push(1); return x.length }\nconsole.log(f(), f())1 1 — the default runs again on each call.
Go deeper
Four layers. Stop at the one your interview needs; each ends with a quick check.
The core ideaEvery round
Object patterns match by name; array patterns match by position. Skip array items with empty commas, and collect the rest with ...rest as the last element.
Check yourself: How do you rename while destructuring?
Use a colon: const { name: buyer } = user.
How it works underneathSenior rounds
undefined. So f(a, b = a * 2) works, and f(x = []) creates a fresh array on each call, unlike Python’s shared default.Check yourself: Can a default refer to an earlier parameter?
Yes. f(a, b = a * 2) works because defaults run left to right.
Edge cases and trapsWhere people slip
Destructuring undefined or null throws a TypeError, so write function f({ a } = {}). Spreading null into an object is allowed and adds nothing, but spreading null into an array throws, because null is not iterable Source: MDN: Spread syntax.
Check yourself: Why does destructuring a function argument often add = {}?
So calling it with no argument destructures {} instead of throwing on undefined.
In productionStaff-level answers
Options objects with defaults ({ retries = 3, timeout = 5000 } = {}) make APIs readable at the call site. Avoid Math.max(...hugeArray) or push(...hugeArray) with hundreds of thousands of items: each item becomes an argument, and that can throw a RangeError Source: MDN: Rest parameters.
Check yourself: What does a.push(...bigArray) risk?
A RangeError: each element becomes an argument, and engines limit argument count.
Finished the five steps? Mark it, and its cards join your reviews.
Last checked 2026-10-31. Spot a mistake? Use “Report an error” below — fixes are listed on the corrections page.
Interview questions this answers
- What is the difference between rest parameters and
arguments?