Spread vs Rest Operators in JavaScript
Modern JavaScript introduced powerful syntax using ... that can behave in two different ways depending on context: spread and rest. While they look identical, their purpose is completely opposite.
Understanding this distinction is critical for writing clean, efficient, and interview-ready code.
πΉ What is the Spread Operator?
The spread operator (...) expands values.
It takes an iterable (like an array or object) and spreads its elements out.
π Simple Example
const arr = [1, 2, 3];
const newArr = [...arr];
console.log(newArr); // [1, 2, 3]
Here, ...arr expands the array into individual elements.
πΉ Spread with Arrays
1. Copying Arrays
const original = [1, 2, 3];
const copy = [...original];
β Creates a shallow copy β Avoids reference issues
2. Merging Arrays
const a = [1, 2];
const b = [3, 4];
const merged = [...a, ...b];
console.log(merged); // [1, 2, 3, 4]
3. Adding Elements
const arr = [2, 3];
const newArr = [1, ...arr, 4];
console.log(newArr); // [1, 2, 3, 4]
πΉ Spread with Objects
const user = { name: "Sayantan" };
const updatedUser = {
...user,
age: 21
};
console.log(updatedUser);
// { name: "Sayantan", age: 21 }
β Common Use Case: Updating State (React / Immutability)
const state = { count: 1 };
const newState = {
...state,
count: state.count + 1
};
πΉ What is the Rest Operator?
The rest operator (...) collects values.
It gathers multiple elements into a single structure (array or object).
π Simple Example
function sum(...numbers) {
return numbers.reduce((acc, curr) => acc + curr, 0);
}
console.log(sum(1, 2, 3, 4)); // 10
Here, ...numbers collects all arguments into an array.
πΉ Rest in Function Parameters
function greet(first, ...others) {
console.log(first); // first value
console.log(others); // remaining values
}
greet("Hi", "Hello", "Hey");
// Hi
// ["Hello", "Hey"]
πΉ Rest with Destructuring (Arrays)
const arr = [1, 2, 3, 4];
const [first, ...rest] = arr;
console.log(first); // 1
console.log(rest); // [2, 3, 4]
πΉ Rest with Objects
const user = {
name: "Sayantan",
age: 21,
city: "Kolkata"
};
const { name, ...rest } = user;
console.log(name); // Sayantan
console.log(rest); // { age: 21, city: "Kolkata" }
π₯ Key Difference: Spread vs Rest
| Feature | Spread Operator (...) |
Rest Operator (...) |
|---|---|---|
| Purpose | Expands values | Collects values |
| Usage Context | Arrays, Objects, Function calls | Function params, Destructuring |
| Direction | Inside β Outside | Outside β Inside |
π§ Mental Model (Very Important)
Spread = EXPAND β Break things apart β "Take values out"
Rest = COLLECT β Group things together β "Put values in"
π Practical Use Cases
1. Cloning Data (Avoid Mutation)
const arr = [1, 2, 3];
const newArr = [...arr];
2. Removing Properties from Objects
const user = { id: 1, name: "Sayantan", password: "1234" };
const { password, ...safeUser } = user;
console.log(safeUser);
// { id: 1, name: "Sayantan" }
3. Flexible Function Arguments
function logAll(...args) {
args.forEach(arg => console.log(arg));
}
4. Combining Data (Real-world API Handling)
const defaultConfig = { theme: "dark", lang: "en" };
const userConfig = { lang: "fr" };
const finalConfig = {
...defaultConfig,
...userConfig
};
console.log(finalConfig);
// { theme: "dark", lang: "fr" }
β οΈ Common Mistakes
β Confusing Context
const arr = [1, 2, 3];
// Spread
console.log(...arr);
// Rest (invalid here β)
// const ...rest = arr;
π Same syntax, different meaning based on position.
β Shallow Copy Issue
const obj = { a: { b: 1 } };
const copy = { ...obj };
copy.a.b = 2;
console.log(obj.a.b); // 2 β οΈ
π Spread does NOT deep clone.
π― Final Takeaway
Both use
..., but:Spread β expands values
Rest β collects values
Context determines behavior
Extremely common in React, APIs, and interviews
If you understand this deeply, you unlock a lot of modern JavaScript patterns.