Spread vs Rest Operators in JavaScript

In this article we'll understand the spread operator and rest operator. Why do we need to know the different in the first place? Well because they both are denoted with same thing and that is 'three dots'. If you're someone who face confusion between them, don't worry then you are not alone. We'll solve the mystery of these ... so that you won't feel confuse about them ever.
What spread operator does
The spread operator is used to "expand" values. It takes something like an array or object and spreads out its elements one by one.
Think of it like opening a packed box and laying everything out.
Example with array:
const arr = [1, 2, 3];
const newArr = [...arr];
console.log(newArr); // [1, 2, 3]
Example with function:
const nums = [5, 10, 15];
function sum(a, b, c) {
return a + b + c;
}
console.log(sum(...nums)); // 30
Here spread takes the array and passes values individually.
What rest operator does
The rest operator does the opposite. Instead of expanding, it collects values into a single structure.
Think of it like packing multiple items into one box.
Example:
function collect(...args) {
console.log(args);
}
collect(1, 2, 3, 4); // [1, 2, 3, 4]
Here all arguments are collected into one array called args.
Another example:
const [first, ...rest] = [10, 20, 30, 40];
console.log(first); // 10
console.log(rest); // [20, 30, 40]
Differences between spread and rest
Even though both use ..., their behaviour depends on where they are used.
Spread:
Expands values
Used when passing or copying data
Mostly seen on right side
Rest:
Collects values
Used in function parameters or destructuring
Mostly seen on left side
Simple way to remember:
Spread = open things
Rest = gather things
Using spread with arrays and objects
Spread with arrays:
const a = [1, 2];
const b = [3, 4];
const combined = [...a, ...b];
console.log(combined); // [1, 2, 3, 4]
Copy array:
const original = [1, 2, 3];
const copy = [...original];
Spread with objects:
const user = { name: "Alex", age: 20 };
const updatedUser = { ...user, age: 21 };
console.log(updatedUser);
// output:
// { name: "Alex", age: 21 };
Merge objects:
const a = { x: 1 };
const b = { y: 2 };
const merged = { ...a, ...b };
console.log(merged)
//output:
// {x:1,y:2}
Practical use cases
- Copying data without mutation
[ note: Spread operator is not recommended with nested array and objects, as they copy only first layer. ]
const arr = [1, 2, 3];
const newArr = [...arr];
- Merging arrays
const all = [...arr1, ...arr2];
- Passing dynamic arguments
Math.max(...numbers);
- Removing properties using rest
const user = { id: 1, name: "Sam", password: "1234" };
const { password, ...safeUser } = user;
console.log(safeUser);
- Handling unknown number of function arguments
function sum(...nums) {
return nums.reduce((a, b) => a + b, 0);
}
At the end, both spread and rest are simple once you understand their intention. Same syntax, different behaviour. Just remember one expands and the other collects, and you will never mix them up again.



