Sign in
Design powerful JS apps 10x faster with prompts
 What’s the real difference between rest and spread in JavaScript? This quick guide breaks down their syntax, use cases, and how to use each one correctly—so you write cleaner, smarter code every time.
Ever found yourself confused by the three dots (...
) in JavaScript code?
These dots represent either the rest operator or the spread operator , depending on the context. Though they look identical, their purposes are entirely different. Understanding these two operators is essential for writing clean, efficient JavaScript, especially when working with arrays, objects, or function arguments.
This blog will demystify the rest vs spread topic, helping you understand their syntax, use cases, and how to avoid common pitfalls. By the end, you’ll be able to use both confidently and correctly in your projects.
In JavaScript, both rest and spread operators use the same ...
syntax. However, they serve different purposes based on their position and usage in the code.
Rest operator: Gathers multiple values into a single array.
Spread operator: Expands an array or object into individual elements.
Let's explore each in detail.
The rest operator is used to collect multiple elements into a new array. This is particularly helpful when working with function parameters, destructuring, or capturing remaining arguments.
The rest operator is used with function parameters or array/object destructuring:
1function collectArgs(...args) { 2 console.log(args); // array of arguments 3}
This gathers all incoming function arguments into one array called args
.
It must be the last parameter in a function.
It cannot be followed by any other function parameters.
Often used when dealing with an indefinite number of values.
Using Rest in Function Parameters:
1function sum(...numbers) { 2 return numbers.reduce((total, num) => total + num, 0); 3} 4console.log(sum(10, 20, 30)); // Output: 60
Using Rest in Destructuring:
1const [first, ...remainingElements] = [1, 2, 3, 4]; 2console.log(first); // 1 3console.log(remainingElements); // [2, 3, 4]
Rest with Objects:
1const { a, ...rest } = { a: 1, b: 2, c: 3 }; 2console.log(a); // 1 3console.log(rest); // { b: 2, c: 3 }
The spread operator is used to convert an iterable object, such as an array or string, into its elements. It can also copy or merge object literals.
The spread operator is used in:
Function calls
Array literals
Object literals
Expanding an Array:
1const nums = [1, 2, 3]; 2console.log(...nums); // 1 2 3
Using Spread in Function Calls:
1function logArgs(a, b, c) { 2 console.log(a, b, c); 3} 4const numbersArray = [100, 200, 300]; 5logArgs(...numbersArray); // 100 200 300
Using Spread to Create a New Array:
1const oldArray = [1, 2]; 2const newArray = [...oldArray, 3]; 3console.log(newArray); // [1, 2, 3]
Merging Objects:
1const obj1 = { name: 'Alice' }; 2const obj2 = { age: 25 }; 3const mergedObj = { ...obj1, ...obj2 }; 4console.log(mergedObj); // { name: 'Alice', age: 25 }
Shallow Copy Caveat:
1const originalObject = { nested: { key: 'value' } }; 2const copiedObject = { ...originalObject }; 3copiedObject.nested.key = 'changed'; 4console.log(originalObject.nested.key); // 'changed'
The spread operator makes a shallow copy, meaning nested key-value pairs are still referenced.
"JavaScript rest vs spread operators explained in 90 seconds, this quick breakdown helped me finally understand when to gather values and when to expand them. A must-watch for anyone confused by the three dots."
— Humayun Athar, via LinkedIn
The diagram shows how JavaScript interprets the same three dots differently. If the ... is used in function parameters; it's a rest operator collecting values. If used in expressions, it's a spread operator expanding them.
Feature | Rest Operator | Spread Operator |
---|---|---|
Syntax Position | Used in function parameters and destructuring | Used in expressions |
Purpose | Collect multiple elements into one | Expand one object or array into multiple |
Typical Use Case | Handling remaining arguments | Merging objects, expanding arrays |
Can be used with | Function parameters, object/array destructuring | Arrays, strings, objects |
Creates | A new array from function arguments | New array or new object by copying |
1const fruits = ['apple', 'banana']; 2const veggies = ['carrot', 'spinach']; 3const food = [...fruits, ...veggies]; // using the spread operator 4console.log(food); // ["apple", "banana", "carrot", "spinach"]
1function describePerson(name, ...traits) { 2 console.log(`Name: ${name}`); 3 console.log(`Traits: ${traits.join(', ')}`); 4} 5describePerson('Sam', 'smart', 'kind', 'funny');
1function addScores(...scores) { 2 const newScores = [...scores, 100]; // using the spread operator 3 console.log(newScores); 4} 5addScores(10, 20, 30);
Use the rest parameter only as the last parameter in a function.
Use spread when you need to create a new array or new object without mutating the original.
Rely on spread for passing arrays to functions that expect individual elements.
Mixing the two operators in the wrong context due to identical syntax.
Forgetting that spread makes a shallow copy, which may affect nested object properties.
Misusing rest in the middle of function parameters, which is not allowed.
Concept | Rest | Spread |
---|---|---|
Collects or Expands? | Collects | Expands |
Used In | Function parameters, destructuring | Function calls, array literals, object literals |
Purpose | Gather remaining elements | Distribute individual elements |
Keyword Context | function f(...args) | f(...argsArray) |
Used With | Parameters | Arguments, arrays, objects |
The rest and spread operators are more than just syntactic sugar; they solve real challenges developers face when working with arrays, objects, and function arguments. By understanding how the rest parameter gathers remaining arguments and how the spread operator expands individual elements, you gain precise control over your data structures and write cleaner, more efficient JavaScript.
Mastering these two operators is crucial for adhering to modern coding standards, preventing common bugs, and improving code readability across your projects.
Start applying what you’ve learned, refactor your existing code, and make the most out of the three dots. The cleaner, smarter way to code is just one operator away.