WasiLearn Code
JavaScript · Arrays and objects

Destructuring and spread

Two pieces of syntax, both written with familiar brackets, that take collections apart and put them back together. They appear in almost every modern JavaScript file, so reading them fluently matters more than most features.

const student = { name: "Ayesha", marks: 72 };
const { name, marks } = student;

console.log(name, marks);
output
Ayesha 72

That is destructuring: pull named properties out into variables of the same name, in one line instead of two.

Object destructuring

const order = { item: "chai", qty: 2, price: 50 };

const { item, qty } = order;
console.log(item, qty);
output
chai 2

The names on the left must match the keys. Order is irrelevant — these are looked up by name, not position — and you may take only the properties you want.

Ask for something that is not there and you get undefined, exactly as with dot notation:

const order = { item: "chai" };
const { item, discount } = order;

console.log(item, discount);
output
chai undefined

Renaming and defaults

const order = { item: "chai", qty: 2 };

const { item: productName, qty, size = "regular" } = order;

console.log(productName, qty, size);
output
chai 2 regular

item: productName renames on the way out — useful when the incoming key clashes with a name you already have. size = "regular" supplies a default.

The default applies only when the value is undefined, not when it is falsy:

const a = { count: 0 };
const b = {};

const { count: countA = 10 } = a;
const { count: countB = 10 } = b;

console.log(countA, countB);
output
0 10

A genuine zero survives. That is ?? behaviour rather than || behaviour, and it is the right choice — the same trap that the logical operators lesson covers.

Array destructuring

Arrays destructure by position, using square brackets.

const marks = [72, 45, 88];
const [first, second] = marks;

console.log(first, second);
output
72 45

Skip items with a bare comma:

const marks = [72, 45, 88];
const [, , third] = marks;

console.log(third);
output
88

Swapping without a temporary falls out of it:

let a = 1;
let b = 2;
[a, b] = [b, a];

console.log(a, b);
output
2 1

And it is why Object.entries loops read the way they do:

const stock = { chai: 12, coffee: 4 };

for (const [item, count] of Object.entries(stock)) {
  console.log(`${item}: ${count}`);
}
output
chai: 12
coffee: 4

Destructuring parameters

This is where it earns its keep. A function taking an options object can name what it needs in the signature:

function describe({ name, marks, grade = "ungraded" }) {
  return `${name}: ${marks} (${grade})`;
}

console.log(describe({ name: "Ayesha", marks: 72 }));
console.log(describe({ name: "Bilal", marks: 88, grade: "A" }));
output
Ayesha: 72 (ungraded)
Bilal: 88 (A)

The signature now documents itself, and the caller cannot get the argument order wrong because there is no order.

One sharp edge: calling it with nothing throws, because you cannot destructure undefined. Default the whole parameter to fix it:

function describe({ name = "unknown" } = {}) {
  return name;
}

console.log(describe());
console.log(describe({ name: "Sana" }));
output
unknown
Sana

That = {} at the end is the part people leave out.

Rest: collecting what is left

Three dots on the left of an assignment gather the remainder.

const marks = [72, 45, 88, 30];
const [top, ...others] = marks;

console.log(top);
console.log(others);
output
72
[ 45, 88, 30 ]
const student = { name: "Ayesha", marks: 72, city: "Karachi" };
const { name, ...rest } = student;

console.log(name);
console.log(rest);
output
Ayesha
{ marks: 72, city: 'Karachi' }

That second pattern is the idiomatic way to remove a property without delete — take out what you do not want, keep rest.

Rest must come last, and there can be only one.

Spread: expanding

The same three dots on the right do the opposite: they spread a collection out into its parts.

const a = [1, 2];
const b = [3, 4];

console.log([...a, ...b]);
console.log([0, ...a, 99]);
console.log([..."chai"]);
output
[ 1, 2, 3, 4 ]
[ 0, 1, 2, 99 ]
[ 'c', 'h', 'a', 'i' ]

For objects, spread copies properties in, and later wins:

const defaults = { size: "regular", sugar: 1 };
const chosen = { sugar: 2 };

console.log({ ...defaults, ...chosen });
console.log({ ...chosen, ...defaults });
output
{ size: 'regular', sugar: 2 }
{ sugar: 1, size: 'regular' }

Order is the entire behaviour. Defaults first, overrides second — reverse it and your defaults overwrite the user's choices.

Updating one field without mutating the original is the everyday use:

const student = { name: "Ayesha", marks: 72 };
const updated = { ...student, marks: 88 };

console.log(student.marks);
console.log(updated.marks);
output
72
88

Spread as arguments

const marks = [72, 45, 88];

console.log(Math.max(...marks));
console.log(Math.max(marks));
output
88
NaN

Math.max takes separate arguments, not an array. Spread turns the array into those arguments; without it the array is converted to a number, which fails.

Rest works in a function definition too — same dots, opposite direction:

function total(...prices) {
  return prices.reduce((sum, p) => sum + p, 0);
}

console.log(total(250, 120, 80));
output
450

Spread copies one level only

The limitation worth knowing before you rely on it.

const original = { name: "Ayesha", marks: { maths: 72 } };
const copy = { ...original };

copy.name = "Bilal";
copy.marks.maths = 100;

console.log(original.name);
console.log(original.marks.maths);
output
Ayesha
100

The top level is independent. Anything nested is shared, because spread copied the reference to marks, not the object. structuredClone(original) is the built-in answer when you need the whole thing independent.

Arrays behave identically:

const rows = [[1, 2], [3, 4]];
const copied = [...rows];

copied[0].push(99);

console.log(rows[0]);
output
[ 1, 2, 99 ]

Reading the dots

The dots always mean the same thing; the side tells you the direction.

  • Left of =, or in a parameter list → rest, collecting into one.
  • Right of =, or in a call, or inside brackets → spread, expanding out.

Next: JSON, which is how these objects travel between a browser and a server.

Prefer learning with a teacher?

WasiLearn Academy runs small-group classes covering this material, online and in Karachi.

See the classes