Skip to main content

Command Palette

Search for a command to run...

Spread vs Rest Operators in JavaScript

Published
5 min read
Spread vs Rest Operators in JavaScript
S
I write code , that run in the browser and someone else's machine. And sometimes I also write articles

When you see three dots ... in JavaScript, it can mean two different things depending on how it is used.

Sometimes it expands values.
Sometimes it collects values.

These two behaviors are called the spread operator and the rest operator.

They look identical, but their purpose depends on context. Understanding the difference becomes easy once you think in terms of:

  • Spread → expanding values

  • Rest → collecting values

Let us build this step by step.


The Spread Operator

The spread operator expands elements from an iterable such as an array or object.

Think of spread as:

Open this container and give me everything inside.

Small Array Example

const numbers = [1, 2, 3];

console.log(...numbers);

Output:

1 2 3

The array is unpacked into individual values.

Without spread, you would see:

[1, 2, 3]

With spread, the array is expanded.


Using Spread with Arrays

Combining Arrays

Before spread, combining arrays required concat().

const arr1 = [1, 2];
const arr2 = [3, 4];

const combined = arr1.concat(arr2);

With spread, it becomes cleaner:

const arr1 = [1, 2];
const arr2 = [3, 4];

const combined = [...arr1, ...arr2];

console.log(combined);

Now visually, you can clearly see that both arrays are expanded into a new one.


Copying Arrays

const original = [10, 20, 30];
const copy = [...original];

console.log(copy);

This creates a shallow copy.

Why is this useful?

Because assigning directly:

const copy = original;

Does not create a new array. It only creates a reference.

Spread creates a new array with the same values.


Adding Elements While Copying

const numbers = [2, 3, 4];

const updated = [1, ...numbers, 5];

console.log(updated);

This expands numbers in the middle of a new array.

This pattern is common in modern JavaScript, especially in state management libraries.


Using Spread with Objects

Spread also works with objects.

Copying Objects

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

const newUser = { ...user };

console.log(newUser);

Again, this creates a shallow copy.


Updating Object Properties

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

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

console.log(updatedUser);

Here is the thinking:

  • Expand all properties of user

  • Override the age property

This pattern is very common in real-world applications.


The Rest Operator

Now let us shift thinking.

If spread means expanding values, rest means collecting them.

Rest gathers multiple values into a single array.


Rest in Function Parameters

Imagine you want a function that accepts any number of arguments.

Without rest, you would rely on older techniques. With rest:

function sum(...numbers) {
  let total = 0;

  for (let num of numbers) {
    total += num;
  }

  return total;
}

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

Here:

  • ...numbers collects all arguments

  • Inside the function, numbers is an array

So if spread opens a box, rest creates a box.


Rest with Array Destructuring

Rest can collect remaining elements.

const numbers = [1, 2, 3, 4, 5];

const [first, second, ...restNumbers] = numbers;

console.log(first);        // 1
console.log(second);       // 2
console.log(restNumbers);  // [3, 4, 5]

Here:

  • The first two elements are assigned individually

  • The remaining values are collected into restNumbers

This is very useful when handling lists.


Rest with Objects

Rest also works with objects.

const user = {
  name: "Alice",
  age: 25,
  country: "USA"
};

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

console.log(name);          // "Alice"
console.log(otherDetails);  // { age: 25, country: "USA" }

The remaining properties are collected into a new object.


Spread vs Rest: Clear Difference

Although they use the same syntax, their purpose is opposite.

Operator Purpose Behavior
Spread Expands values Breaks array or object into individual elements
Rest Collects values Gathers multiple elements into an array or object

The key mental model:

  • Spread → unpack

  • Rest → pack


Real-World Usage Patterns

Spread is commonly used for:

  • Copying arrays or objects

  • Merging arrays

  • Updating state immutably

  • Passing array elements as function arguments

Example:

const numbers = [1, 2, 3];

Math.max(...numbers);

Rest is commonly used for:

  • Functions with dynamic arguments

  • Extracting certain properties while grouping others

  • Handling flexible input

Example:

function logMessages(firstMessage, ...otherMessages) {
  console.log(firstMessage);
  console.log(otherMessages);
}

logMessages("Hello", "How", "Are", "You");

Seeing Both Together

const numbers = [1, 2, 3];

function multiply(multiplier, ...values) {
  return values.map(value => value * multiplier);
}

console.log(multiply(2, ...numbers));

Here:

  • Spread expands numbers into individual arguments

  • Rest collects them back into values

Both operators work together in a complementary way.


Summary

The three dots ... serve two different roles depending on context.

If they appear:

  • In array or object literals → they expand values

  • In function parameters or destructuring → they collect values

Spread expands.
Rest collects.

Understanding this expansion vs collection mindset makes it much easier to use them correctly in real-world JavaScript applications.