Skip to main content

Command Palette

Search for a command to run...

Spread vs Rest Operators in JavaScript

Do You Know Spread And Rest Operators ?

Updated
•3 min read•View as Markdown
Spread vs Rest Operators in JavaScript

Introduction

At first glance, the spread (...) and rest (...) operators look identical. Same syntax, same three dots, often used in similar places. That similarity is exactly why many developers confuse them.

But they serve opposite purposes.

One expands values. The other collects them.

If you don’t understand that distinction clearly, you’ll end up using them mechanically rather than intentionally.

In this article I will break down both operators in a way that makes their behavior predictable and practical.

So let's get started...

Understanding the Spread Operator

The spread operator takes an iterable (like an array or string) and expands it into individual elements.

const arr = [1, 2, 3];
console.log(...arr); // 1 2 3

Instead of treating the array as a single unit, spread breaks it apart.

https://images.openai.com/static-rsc-4/YnZgmJ04y74miL7g5_nRIEb24ZQZHlyzkeALuP19W6FF68fWBuIMn5_06-B8ElovLUkrqYIxbFRhwYUtf5VGXb4zt7kl64nwBFA2fTFdSNwL_kwjn0kS90oeS_XVqHOpyMC7i7PWdbnO5klWDNjliieWlShN2naBX7ugi1e63jX3_QTljOnqspm6wQoHz3oe?purpose=fullsize

This behavior becomes useful when you need to copy, merge, or pass values.

Example: Copying an Array

const original = [1, 2, 3];
const copy = [...original];

This creates a shallow copy. It’s not the same reference.

Example: Merging Arrays

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

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

No loops. No manual concatenation. Just expansion.

Example: Using Spread with Objects

const user = { name: "Alice" };
const updatedUser = { ...user, age: 25 };

Here, properties are expanded into a new object.

Important detail: if keys overlap, later values overwrite earlier ones.

Understanding the Rest Operator

The rest operator does the opposite. It collects multiple elements into a single structure.

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

sum(1, 2, 3); // 6

Here, all arguments are gathered into the numbers array.

https://images.openai.com/static-rsc-4/KBT6PJfcdrO687DZHaBD9_7_doahA2HRzxhE5cDK7YVb6NwCbvClfSYEDMvZnhQjp8WRuOvWF_NlguVh3M7RlXjaA3sDXpO3r-X-9xv5q-q5lwqNmaBwiX4oURI13LvWK-d0o5aeqk6Z4ss4-tB-RpUe1TMQK8Bbi5lfPUkV4RMOYjCIK8XEsAt7DYK77gOx?purpose=fullsize

Instead of expanding, rest consolidates.

Example: Array Destructuring

const arr = [1, 2, 3, 4];

const [first, ...rest] = arr;

console.log(first); // 1
console.log(rest);  // [2, 3, 4]

Here, rest collects remaining elements after extracting the first.

Example: Object Destructuring

const user = { name: "Alice", age: 25, city: "Delhi" };

const { name, ...others } = user;

console.log(others); // { age: 25, city: "Delhi" }

Again, it gathers what’s left.

The Core Difference: Expanding vs Collecting

Here’s a quick comparison:

Aspect Spread Rest
Purpose Expand values Collect values
Usage Arrays, objects, function calls Function params, destructuring
Direction One → many Many → one

Where Developers Go Wrong

Let’s be precise.

  • They treat spread and rest as interchangeable

  • They don’t understand shallow copying

  • They misuse spread with nested objects expecting deep cloning

  • They fail to recognize context (function vs destructuring)

Example mistake:

const obj = { a: { b: 1 } };
const copy = { ...obj };

copy.a.b = 2;
console.log(obj.a.b); // 2

Spread does not perform deep copy. That assumption causes bugs.

A Practical Mental Model

If you’re unsure which one to use, ask:

  • Am I breaking something apart? → use spread

  • Am I gathering remaining values? → use rest

This simple question eliminates confusion in most cases.

Conclusion

The spread and rest operators are not complex, but they are often misunderstood because they share the same syntax while doing opposite things.

Once you internalize:

  • Spread expands

  • Rest collects

their usage becomes intuitive rather than memorized.