Gyaan

Spread & Rest Operators

beginner ES6 spread rest arrays objects

The ... syntax in JavaScript does two different things depending on where we use it. This confuses a lot of people because they look identical. The simple rule is:

  • Spread = expands/unpacks elements (used when we are providing values)
  • Rest = collects/gathers elements (used when we are receiving values)
Spread (expands)
[...arr] — copy array
{...obj} — copy object
fn(...args) — pass as args
[1, 2, 3] becomes 1, 2, 3
Rest (collects)
fn(...params) — gather args
[a, ...rest] — remaining items
{a, ...rest} — remaining props
1, 2, 3 becomes [1, 2, 3]

Spread with arrays

We can use spread to copy arrays, merge them, or pass array elements as function arguments:

const nums = [1, 2, 3];

// Copy an array (shallow copy)
const copy = [...nums];

// Merge arrays
const more = [0, ...nums, 4, 5]; // [0, 1, 2, 3, 4, 5]

// Pass as function arguments
console.log(Math.max(...nums)); // 3

Spread with objects

Same idea works with objects. We can copy, merge, or override properties:

const user = { name: "Manish", age: 25 };

// Copy an object (shallow copy)
const copy = { ...user };

// Merge objects (later properties override earlier ones)
const updated = { ...user, age: 26, city: "Pune" };
// { name: "Manish", age: 26, city: "Pune" }

When merging objects, if two objects have the same key, the last one wins:

const defaults = { theme: "light", lang: "en" };
const prefs = { theme: "dark" };
const config = { ...defaults, ...prefs };
// { theme: "dark", lang: "en" } — prefs overrides defaults

Rest in function parameters

Rest collects all remaining arguments into an array. This replaces the old arguments object with a real array:

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

console.log(sum(1, 2, 3, 4)); // 10

We can also combine regular parameters with rest — but rest must always be last:

function log(level, ...messages) {
  messages.forEach(msg => console.log(`[${level}] ${msg}`));
}

log("INFO", "Server started", "Listening on port 3000");

Rest in destructuring

Rest works in both array and object destructuring to capture “everything else”:

// Array destructuring with rest
const [first, ...remaining] = [1, 2, 3, 4];
console.log(first);     // 1
console.log(remaining); // [2, 3, 4]

// Object destructuring with rest
const { name, ...details } = { name: "Manish", age: 25, city: "Pune" };
console.log(name);    // "Manish"
console.log(details); // { age: 25, city: "Pune" }

Common interview question

What is the difference between spread and rest?

They use the same ... syntax but do opposite things. Spread expands an iterable into individual elements (we are giving values out). Rest collects multiple individual elements into a single array or object (we are gathering values in). The context tells us which one it is — if ... appears in a function definition or destructuring pattern, it is rest. If it appears in a function call, array literal, or object literal, it is spread.

// Spread — expanding values
const arr = [...[1, 2], ...[3, 4]]; // [1, 2, 3, 4]

// Rest — collecting values
const [first, ...rest] = arr; // first = 1, rest = [2, 3, 4]

In simple language, spread is like opening a box and spilling everything out. Rest is like sweeping everything remaining into a box.