Destructuring, Rest & Spread
Modern JavaScript code is full of square and curly brackets on the left of an = sign, and of three dots ... in front of names. These are destructuring, rest and spread, three short syntaxes for taking data apart and putting it back together. Once you know them, you will read React, Node.js and most library code much more easily.
In this lesson you will unpack arrays and objects into variables, use defaults and renaming, collect the remaining items with rest, and copy and merge arrays and objects with spread.
Array destructuring
Destructuring means unpacking values from an array or object into separate variables in one line. For arrays, you write square brackets on the left of =, and variables are filled by position.
const toppers = ["Meera", "Farhan", "Kabir", "Isha"];
const [first, second] = toppers;
console.log(first, second);
const [, , third] = toppers;
console.log(third);
const [winner, ...others] = toppers;
console.log(winner, others);
const [a, b, c, d, fifth = "No one"] = toppers;
console.log(fifth);Meera Farhan Kabir Meera [ 'Farhan', 'Kabir', 'Isha' ] No one
[first, second]takes the first two items; the rest are ignored.- Empty places between commas skip items:
[, , third]takes the third. ...othersis a rest element: it collects all remaining items into a new array. It must come last.fifth = "No one"is a default value, used when there is no item at that position (or the item isundefined).
A neat trick: destructuring can swap two variables without a temporary variable.
let left = "Chai";
let right = "Coffee";
[left, right] = [right, left];
console.log(left, right);Coffee Chai
Object destructuring
For objects, you write curly braces on the left, and variables are matched by key name, not by position.
const booking = { pnr: "4521367890", passenger: "Ananya", coach: "B3", berth: 34 };
const { passenger, coach } = booking;
console.log(passenger, coach);
const { berth: seatNumber, meal = "Not booked" } = booking;
console.log(seatNumber, meal);
const { pnr, ...details } = booking;
console.log(pnr);
console.log(details);Ananya B3
34 Not booked
4521367890
{ passenger: 'Ananya', coach: 'B3', berth: 34 }{ passenger, coach }creates two variables with the same names as the keys. Order does not matter.berth: seatNumberrenames: it reads theberthproperty into a variable calledseatNumber. Read the colon as "goes into".meal = "Not booked"gives a default becausebookinghas nomeal....detailscollects all the other properties into a new object.
You can also destructure nested data by repeating the pattern: const { customer: { city } } = order; reads order.customer.city into city. Keep nesting shallow, though; deep patterns are hard to read, and they throw if a middle level is missing.
Destructuring function parameters
This is where destructuring is used most. When a function takes several settings, pass one object and destructure it in the parameter list. Callers can then give the settings in any order and skip the ones that have defaults.
function bookTicket({ from, to, travelClass = "SL", passengers = 1 }) {
return `${passengers} x ${travelClass}: ${from} to ${to}`;
}
console.log(bookTicket({ from: "Jaipur", to: "Delhi" }));
console.log(bookTicket({ to: "Kochi", from: "Pune", travelClass: "3A", passengers: 2 }));1 x SL: Jaipur to Delhi 2 x 3A: Pune to Kochi
Compare this with bookTicket("Pune", "Kochi", "3A", 2), where a reader must remember what the third and fourth arguments mean. Named settings explain themselves.
Spread with arrays
The spread syntax ... does the opposite of rest: it expands an array (or any iterable) into separate values, right where you write it.
const morning = ["Idli", "Dosa"];
const evening = ["Samosa", "Pakora"];
const menu = [...morning, "Thali", ...evening];
console.log(menu);
const copy = [...menu];
console.log(copy === menu);
const prices = [40, 120, 85];
console.log(Math.max(...prices));
console.log([..."PUNE"]);[ 'Idli', 'Dosa', 'Thali', 'Samosa', 'Pakora' ] false 120 [ 'P', 'U', 'N', 'E' ]
[...a, ...b]joins arrays, and you can add items anywhere in between.[...menu]makes a new array with the same items: a quick copy.Math.max(...prices)passes each price as a separate argument, becauseMath.max()does not accept an array.- Spreading a string gives an array of its characters.
Spread with objects
Spread also works inside object literals. It copies all properties of one object into a new one. When two objects have the same key, the one written later wins.
const defaults = { theme: "light", language: "English", fontSize: 16 };
const saved = { language: "Hindi", fontSize: 18 };
const settings = { ...defaults, ...saved };
console.log(settings);
const darkSettings = { ...settings, theme: "dark" };
console.log(darkSettings.theme, settings.theme);{ theme: 'light', language: 'Hindi', fontSize: 18 }
dark lightThis pattern, defaults first and the user's choices after, is very common. The last line shows how to "change" an object without touching the original: copy it and override one property. Frameworks such as React rely on this style of update.
Rest or spread?
Both use three dots. The position tells you which one it is:
Where the ... appears | Name | What it does |
|---|---|---|
Left of = in destructuring | Rest | Collects remaining items or properties |
| In a function's parameter list | Rest parameter | Collects remaining arguments into an array |
Inside [ ] or { } on the right | Spread | Expands items or properties into the new array or object |
| Inside a function call's brackets | Spread | Expands an array into separate arguments |
Rest parameters were introduced in Functions. In short: rest gathers, spread scatters.
Common mistakes
- Destructuring
undefined.const { city } = undefined;throws aTypeError. Give function parameters a default:function f({ a } = {}). - Rest not at the end.
const [...rest, last] = list;is a syntax error. Rest must be last. - Wrong order when merging.
{ ...saved, ...defaults }lets the defaults overwrite the user's choices. Put the values that should win last. - Expecting a deep copy from spread. Nested arrays and objects are shared.
- Confusing rename and default.
{ a: b }renamesatob;{ a = 5 }givesaa default.
Key points
- Array destructuring unpacks by position; object destructuring unpacks by key.
- Use
key: newNameto rename and= valuefor defaults. - A rest element (
...rest) collects what is left and must come last. - Destructured object parameters give functions clear, named, optional settings.
- Spread (
...) expands arrays into items or arguments and copies object properties; later keys win. - Spread copies are shallow.
Exercise
A student record arrives as { name: "Isha", marks: [78, 91, 66], city: "Rohtak", year: 2 }. Use object destructuring to get name and marks, and collect everything else into rest. Then use array destructuring to get the first mark and the remaining marks. Finally, create a new object that has all of the original properties plus year: 3, without changing the original, and print both years.
Show solution
const record = { name: "Isha", marks: [78, 91, 66], city: "Rohtak", year: 2 };
const { name, marks, ...rest } = record;
const [firstMark, ...otherMarks] = marks;
console.log(name, firstMark, otherMarks);
console.log(rest);
const promoted = { ...record, year: 3 };
console.log(record.year, promoted.year);Isha 78 [ 91, 66 ]
{ city: 'Rohtak', year: 2 }
2 3Rest in object destructuring gathers city and year. Spread copies record and the later year: 3 overrides the copied value, so the original stays at year 2.
Quick Quiz
1. What is x after const [, x] = [10, 20, 30];?
The empty place before the comma skips the first item, so x gets the second.
2. What does const { price: cost } = { price: 99 }; create?
The colon renames: the price property goes into a variable named cost.
3. What is { ...{ a: 1, b: 2 }, b: 5 }?
Properties written later overwrite earlier ones with the same key.
4. Which call passes the numbers of list as separate arguments?
Spread inside a call's brackets expands the array into separate arguments.
Learn JavaScript with a mentor
Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
