Skip to main content

Command Palette

Search for a command to run...

Spread vs Rest Operators in JavaScript

Understanding the Power of `...` in JavaScript: Expanding vs Collecting Values

Updated
•3 min read•View as Markdown

Spread vs Rest Operators in JavaScript

Same syntax, Different jobs.

If you've worked with modern JavaScript, you have probably seen ... (three dots) syntax everywhere.

At first if feels confusing. Sometimes it expands values, sometimes it collects them. That is because this same syntax is used for two different things.

  • Spread Operator --> expands values

  • Rest Operator --> collects values

Let's discuss it down in a simple way.


What is Spread Operator?

The spread operator is used to expand elements. Think of it like opening a box and laying everything out.
Example with Arrays

const nums = [1, 2, 3];

const newNums = [...nums, 4, 5];

console.log(newNums);
// [1, 2, 3, 4, 5]
  • ...nums spreads the array values

  • It becomes 1, 2, 3


What is the Rest Operator?

The rest operator is used to collect multiple values into one. Think of it like putting things into a box.

Example with Function Parameters

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

console.log(sum(1, 2, 3, 4))
// 10
  • ...numbers collects all arguments into an array

  • numbers = [1, 2, 3, 4]


Key Difference (Core idea)

Spread Rest
Expands values Collects values
Used while sending data Used while receiving data
Appears in function calls, arrays, objects Appears in function parameters, destructuring

Simple way to remember:

  • Spread = unpack

  • Rest = pack


Merge Arrays

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

const merged = [...a, ...b];

//Result
[1, 2, 3, 4]

Using Spread with Objects

Copy an Object

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

const newUser = {...user};

Update Object Values

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

const updatedUser = {
...user,
age: 26
};

here old values are copied then overridden.


Using Rest in Destructuring

Arrays

const name = [1, 2, 3, 4]

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

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

Objects

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

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

console.log(name); // John
conole.log(rest); // { age: 25, city: "Delhi" }

Practical Use Cases

1. Avoid Mutating Data

const original = [1, 2, 3];
const updated = [...original, 4];

You keep the original safe.

2. Flexible Functions

function logAll(...args) {
  console.log(args);
}

logAll(1, "hello", true);

Works with any number of inputs.

3. Combine Data Easily

const defaultSettings = { theme: "light" };
const userSettings = { fontSize: 16 };

const finalSettings = {
  ...defaultSettings,
  ...userSettings
};

One Important Detail (Edge Case)

const user = {
  name: "John",
  address: { city: "Delhi" }
};

const copy = { ...user };

copy.address.city = "Mumbai";

console.log(user.address.city);
// Mumbai 😬

Why?

Because nested objects are still shared by reference.


Fixing the Shallow Copy Problem (Deep Copy in JavaScript)

Using structuredClone() (Modern & Clean)

const user = {
  name: "John",
  address: { city: "Delhi" }
};

const deepCopy = structuredClone(user);

deepCopy.address.city = "Mumbai";

console.log(user.address.city);
// Delhi ✅

1 views