Skip to main content

Command Palette

Search for a command to run...

Spread vs Rest Operators in JavaScript

Updated
3 min readView as Markdown
Spread vs Rest Operators in JavaScript

If you've been writing JavaScript for a while, you've probably seen ... pop up in code and wondered — wait, what is this doing here? Sometimes it's expanding things, sometimes it's collecting things. Same syntax, two very different jobs.

Let's break it down simply.

1. What Spread Operator Does

The spread operator expands an array or object into individual pieces.

Think of it like unpacking a box — you take everything out and lay it on the table.

const fruits = ["apple", "banana", "mango"];
console.log(...fruits); // apple banana mango

You're not passing an array anymore — you're passing three separate values. That's what spread does. It opens things up.

2. What Rest Operator Does

The rest operator does the opposite — it collects multiple values and packs them into one array.

Think of it like gathering scattered things into a bag.

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

total(1, 2, 3, 4); // 10

Here, no matter how many arguments you pass, rest grabs them all and puts them in a numbers array. Clean and flexible.

3. Differences Between Spread and Rest

They look the same (...) but they work in opposite directions:

Spread Rest
What it does Expands values outward Collects values inward
Where it's used Function calls, array/object literals Function parameters, destructuring
Think of it as Unpacking Packing

A quick way to tell them apart — if ... is on the receiving end (like in a function parameter), it's rest. If it's on the giving end (like when you're passing or copying), it's spread.

4. Using Spread with Arrays and Objects

Combining arrays:

const a = [1, 2, 3];
const b = [4, 5, 6];
const combined = [...a, ...b]; // [1, 2, 3, 4, 5, 6]

Copying an array without linking it:

const original = [1, 2, 3];
const copy = [...original];
copy.push(4);

console.log(original); // [1, 2, 3] — untouched
console.log(copy);     // [1, 2, 3, 4]

Spreading into objects:

const user = { name: "Rohan", age: 25 };
const updatedUser = { ...user, city: "Mumbai" };
// { name: "Rohan", age: 25, city: "Mumbai" }

This is super useful when you want to add or override fields without mutating the original object.

5. Practical Use Cases

Merging config objects (common in React and Node):

const defaultConfig = { theme: "light", lang: "en" };
const userConfig = { lang: "hi", fontSize: 16 };

const finalConfig = { ...defaultConfig, ...userConfig };
// { theme: "light", lang: "hi", fontSize: 16 }

User config wins over defaults — simple and readable.

Passing array items to a function:

const nums = [5, 10, 3];
Math.max(...nums); // 10

Without spread, Math.max([5, 10, 3]) would return NaN. Spread fixes that.

Rest in destructuring — grab what you need, collect the rest:

const [first, second, ...remaining] = [10, 20, 30, 40, 50];
console.log(first);     // 10
console.log(remaining); // [30, 40, 50]

Wrapping Up

Same three dots, two different purposes:

  • Spread = open it up, expand values outward

  • Rest = pack it up, collect values inward

Once this clicks, you'll start seeing ... everywhere in modern JavaScript — and it'll make complete sense every time.