JavaScript: Spread vs Rest Operators
Introduced in ES6, the three dots syntax (...) can be highly confusing for beginners because it performs two completely opposite functions depending on where it is used.
What is the difference between the Spread operator and the Rest operator?
Put simply: Spread "unpacks" elements, while Rest "packs" elements.
1. The Spread Operator (Unpacking)
The Spread operator allows an iterable (like an Array or String) or an Object to be expanded in places where zero or more arguments or elements are expected.
It is primarily used for:
- Copying arrays/objects (shallow copy)
- Merging arrays/objects
- Passing array elements as function arguments
Array Examples
const numbers = [1, 2, 3];
// 1. Copying an array
const copy = [...numbers];
// 2. Merging arrays
const moreNumbers = [...numbers, 4, 5]; // [1, 2, 3, 4, 5]
// 3. Passing to a function
console.log(Math.max(...numbers)); // 3 (Expands to Math.max(1, 2, 3))Object Examples
const user = { name: "Alice", age: 25 };
// Merging and updating objects
const updatedUser = { ...user, age: 26, role: "Admin" };
// { name: "Alice", age: 26, role: "Admin" }2. The Rest Parameter (Packing)
The Rest parameter does the exact opposite: it collects multiple elements and condenses them into a single array.
It is primarily used in:
- Function parameters (to gather an indefinite number of arguments)
- Destructuring assignments (to gather remaining properties)
Function Arguments Example
Instead of using the clunky, array-like arguments object, modern JavaScript uses Rest parameters to gather arguments into a true array.
function sum(firstItem, ...remainingItems) {
console.log(firstItem); // 1
console.log(remainingItems); // [2, 3, 4]
// Since remainingItems is a real array, we can use array methods!
return firstItem + remainingItems.reduce((acc, curr) => acc + curr, 0);
}
sum(1, 2, 3, 4); Rule: The Rest parameter must always be the last parameter in a function definition.
Destructuring Example
const fruits = ["Apple", "Banana", "Cherry", "Date"];
const [first, second, ...restOfFruits] = fruits;
console.log(first); // "Apple"
console.log(restOfFruits); // ["Cherry", "Date"]Summary Table
| Feature | Spread (...) | Rest (...) |
|---|---|---|
| Purpose | Unpacks / Expands elements | Packs / Collects elements |
| Data Structure | Works on Arrays, Objects, Strings | Results in an Array (or Object in destructuring) |
| Placement | Used in function calls, array/object literals | Used in function definitions, destructuring patterns |
| Constraint | Can be used anywhere in the literal/arguments | Must be the last element/parameter |
Senior-Level Interview Answer
Despite sharing the exact same syntax (
...), Spread and Rest serve opposite paradigms. The Spread syntax expands an iterable or object into individual elements, making it the modern standard for shallow copying, merging structures, and applying array elements as function arguments withoutFunction.prototype.apply(). Conversely, the Rest syntax collects multiple elements into a single array structure. It is heavily utilized in destructuring assignments to capture remaining properties, and in function declarations to handle variadic arguments cleanly, fully replacing the legacyargumentsobject.
Common Interview Mistakes
❌ Putting the Rest parameter in the wrong order
A guaranteed syntax error is trying to place a Rest parameter before other standard parameters.
// SyntaxError: Rest parameter must be last formal parameter
function test(...args, lastParam) { } ❌ Assuming Spread creates a Deep Copy
Candidates often use const newObj = { ...oldObj } and claim it fully clones the object. Spread only performs a shallow copy. If oldObj contains nested objects or arrays, the references to those nested structures are copied, not the underlying data.
