JavaScript 23 🧬 rest parameters
Rest parameters provide a way to handle an indefinite number of arguments as an array. They were introduced in ES6 (ECMAScript 2015) and offer a more concise syntax for working with functions that accept a variable number of arguments.
A Quick Look at the Examples
// 1. Sum any number of arguments
function sum(...numbers) {
return numbers.reduce((acc, curr) => acc + curr, 0);
}
console.log(sum(1, 2, 3)); // 6
console.log(sum(4, 5, 6, 7, 8)); // 30
// 2. First argument + rest as array
function greet(greeting, ...names) {
names.forEach(name => console.log(`${greeting}, ${name}!`));
}
greet("Hello", "Alice", "Bob", "Charlie");
// Hello, Alice!
// Hello, Bob!
// Hello, Charlie!
// 3. Multiplier + rest as values
function multiply(multiplier, ...values) {
return values.map(value => multiplier * value);
}
console.log(multiply(2, 1, 3, 4)); // [2, 6, 8]
a. Rest Parameters Introduction
Rest parameters provide a way to handle an indefinite number of arguments as an array. They were introduced in ES6 (ECMAScript 2015).
They offer a more concise syntax for working with functions that accept a variable number of arguments.
Key Rules
| Rule | Description |
|---|---|
| Must be last | The rest parameter must be the last parameter in a function definition |
| Only one | Only one rest parameter can be used per function |
| Collects extras | Gathers all remaining arguments into an array |
| Array methods | The rest parameter is a real array — you can use map, filter, reduce, etc. |
Syntax
function functionName(param1, param2, ...restOfParams) {
// ...
}
param1andparam2— regular parameters...restOfParams— the rest parameter, which collects all additional arguments passed
Visual:
function greet(greeting, ...names) { }
│ │
│ └── Rest parameter (array)
└── Regular parameter (first argument)
greet("Hello", "Alice", "Bob", "Charlie")
│ │ │ │
│ └───────┴───────┴── Collected into names = ["Alice", "Bob", "Charlie"]
└── Assigned to greeting = "Hello"
Rest Parameters vs the arguments Object
| Aspect | Rest Parameters | arguments Object |
|---|---|---|
| Type | Real array | Array-like object |
| Array methods | ✅ Yes (map, filter, etc.) | ❌ No |
| Works in arrow functions | ✅ Yes | ❌ No |
| Named | ✅ Yes | ❌ No (always arguments) |
| Includes all args? | ❌ Only extras (after named params) | ✅ All arguments |
| ES version | ES6 (2015) | ES1 (1997) |
// ✅ Rest parameters — real array, works in arrow functions
const sum = (...nums) => nums.reduce((a, b) => a + b, 0);
// ❌ arguments object — not available in arrow functions, not a real array
function sumOld() {
// arguments is array-like, no .reduce()
return Array.from(arguments).reduce((a, b) => a + b, 0);
}
Rest Parameters with Destructuring
Rest parameters work well with destructuring assignment, allowing you to extract specific elements from an array while collecting the rest.
// Array destructuring
const [first, second, ...rest] = [1, 2, 3, 4, 5];
console.log(first); // 1
console.log(second); // 2
console.log(rest); // [3, 4, 5]
// Object destructuring
const { a, b, ...others } = { a: 1, b: 2, c: 3, d: 4 };
console.log(a); // 1
console.log(b); // 2
console.log(others); // { c: 3, d: 4 }
b. Rest Parameters Use Cases and Examples
Use Cases
| # | Use Case | Description |
|---|---|---|
| 1 | Flexible functions | Handle any number of arguments |
| 2 | Variadic functions | Simplify functions with variable parameters |
| 3 | Destructuring | Separate specific elements from the rest |
Example 1: Sum Any Number of Arguments
function sum(...numbers) {
return numbers.reduce((acc, curr) => acc + curr, 0);
}
console.log(sum(1, 2, 3)); // 6
console.log(sum(4, 5, 6, 7, 8)); // 30
console.log(sum()); // 0
console.log(sum(10)); // 10
How it works:
numbersis an array containing all argumentsreduce()sums them- Works with any number of arguments — including zero
Example 2: Regular Parameter + Rest
function greet(greeting, ...names) {
names.forEach(name => console.log(`${greeting}, ${name}!`));
}
greet("Hello", "Alice", "Bob", "Charlie");
// Hello, Alice!
// Hello, Bob!
// Hello, Charlie!
How it works:
greetinggets the first argument ("Hello")namescollects the rest into an array (["Alice", "Bob", "Charlie"])
Visual:
greet("Hello", "Alice", "Bob", "Charlie")
│ └────────┬───────────────┘
│ │
greeting = "Hello" names = ["Alice", "Bob", "Charlie"]
Example 3: Map with Multiplier
function multiply(multiplier, ...values) {
return values.map(value => multiplier * value);
}
console.log(multiply(2, 1, 3, 4)); // [2, 6, 8]
How it works:
multipliergets the first argument (2)valuescollects the rest into an array ([1, 3, 4])map()multiplies each by the multiplier
Complete Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Rest Parameters</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
background: #f8f9fa;
color: #333;
line-height: 1.6;
}
h1 { color: #007bff; border-bottom: 3px solid #007bff; padding-bottom: 10px; }
h2 { color: #28a745; border-left: 4px solid #28a745; padding-left: 15px; margin-top: 30px; }
.demo-box {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
margin: 15px 0;
}
pre {
background: #1e1e1e;
color: #d4d4d4;
padding: 15px;
border-radius: 8px;
overflow-x: auto;
font-family: 'Courier New', monospace;
font-size: 0.9rem;
line-height: 1.8;
}
.keyword { color: #569cd6; }
.string { color: #ce9178; }
.number { color: #b5cea8; }
.function { color: #dcdcaa; }
.comment { color: #6a9955; }
.boolean { color: #569cd6; }
#output {
background: #e9ecef;
padding: 15px;
border-radius: 8px;
margin-top: 15px;
min-height: 40px;
font-family: 'Courier New', monospace;
font-size: 0.85rem;
border-left: 4px solid #007bff;
white-space: pre-wrap;
}
table {
width: 100%;
border-collapse: collapse;
margin: 15px 0;
}
th, td {
padding: 10px;
border: 1px solid #ddd;
text-align: left;
}
th { background: #007bff; color: white; }
tr:nth-child(even) { background: #f8f9fa; }
.btn {
padding: 10px 20px;
background: #007bff;
color: white;
border: none;
border-radius: 6px;
font-size: 1em;
font-weight: bold;
cursor: pointer;
margin: 5px;
transition: all 0.3s;
}
.btn:hover {
background: #0056b3;
transform: translateY(-2px);
}
.btn-success { background: #28a745; }
.btn-success:hover { background: #1e7e34; }
.input-group {
margin: 10px 0;
}
.input-group label {
display: inline-block;
min-width: 150px;
font-weight: bold;
}
.input-group input {
padding: 8px 12px;
border: 2px solid #ddd;
border-radius: 6px;
font-size: 1em;
width: 300px;
}
.input-group input:focus {
outline: none;
border-color: #007bff;
}
.result-display {
font-family: 'Courier New', monospace;
font-size: 1.2em;
color: #007bff;
background: #f8f9fa;
padding: 15px;
border-radius: 8px;
margin: 10px 0;
border-left: 4px solid #007bff;
}
</style>
</head>
<body>
<h1>Rest Parameters</h1>
<div class="demo-box">
<h2>1. Basic Example — Sum Any Number</h2>
<pre>
<span class="keyword">function</span> <span class="function">sum</span>(...numbers) {
<span class="keyword">return</span> numbers.<span class="function">reduce</span>((acc, curr) => acc + curr, <span class="number">0</span>);
}
console.log(<span class="function">sum</span>(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>)); <span class="comment">// 6</span>
console.log(<span class="function">sum</span>(<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>)); <span class="comment">// 30</span>
</pre>
</div>
<div class="demo-box">
<h2>2. Regular Parameter + Rest</h2>
<pre>
<span class="keyword">function</span> <span class="function">greet</span>(greeting, ...names) {
names.<span class="function">forEach</span>(name => console.log(<span class="string">`${greeting}, ${name}!`</span>));
}
<span class="function">greet</span>(<span class="string">"Hello"</span>, <span class="string">"Alice"</span>, <span class="string">"Bob"</span>, <span class="string">"Charlie"</span>);
<span class="comment">// Hello, Alice!
// Hello, Bob!
// Hello, Charlie!</span>
</pre>
</div>
<div class="demo-box">
<h2>3. Multiply with Rest</h2>
<pre>
<span class="keyword">function</span> <span class="function">multiply</span>(multiplier, ...values) {
<span class="keyword">return</span> values.<span class="function">map</span>(value => multiplier * value);
}
console.log(<span class="function">multiply</span>(<span class="number">2</span>, <span class="number">1</span>, <span class="number">3</span>, <span class="number">4</span>)); <span class="comment">// [2, 6, 8]</span>
</pre>
</div>
<div class="demo-box">
<h2>4. Rest Parameters vs arguments Object</h2>
<table>
<tr>
<th>Aspect</th>
<th>Rest Parameters</th>
<th><code>arguments</code></th>
</tr>
<tr>
<td><strong>Type</strong></td>
<td>Real array</td>
<td>Array-like object</td>
</tr>
<tr>
<td><strong>Array methods</strong></td>
<td>✅ Yes (<code>map</code>, <code>filter</code>, ...)</td>
<td>❌ No</td>
</tr>
<tr>
<td><strong>Arrow functions</strong></td>
<td>✅ Yes</td>
<td>❌ No</td>
</tr>
<tr>
<td><strong>Named</strong></td>
<td>✅ Yes</td>
<td>❌ No (always <code>arguments</code>)</td>
</tr>
<tr>
<td><strong>ES version</strong></td>
<td>ES6 (2015)</td>
<td>ES1 (1997)</td>
</tr>
</table>
</div>
<div class="demo-box">
<h2>5. Interactive: Sum Playground</h2>
<div class="input-group">
<label for="numbersInput">Enter numbers (comma-separated):</label>
<input type="text" id="numbersInput" value="1, 2, 3, 4, 5">
</div>
<div style="margin: 10px 0;">
<button class="btn btn-success" onclick="runSum()">Sum</button>
<button class="btn" onclick="runMax()">Max</button>
<button class="btn" onclick="runMin()">Min</button>
<button class="btn" onclick="runAverage()">Average</button>
<button class="btn" onclick="runProduct()">Product</button>
</div>
<div class="result-display" id="resultDisplay">Result will appear here</div>
<div id="operationDetails"></div>
</div>
<div class="demo-box">
<h2>6. Live Output — All Examples</h2>
<div id="output">Loading...</div>
</div>
<script>
// ============================================
// Rest Parameters — Live Demo
// ============================================
let results = [];
// 1. Sum any number
results.push('📌 Sum Any Number:\n');
function sum(...numbers) {
return numbers.reduce((acc, curr) => acc + curr, 0);
}
results.push(' sum(1, 2, 3) → ' + sum(1, 2, 3));
results.push(' sum(4, 5, 6, 7, 8) → ' + sum(4, 5, 6, 7, 8));
results.push(' sum() → ' + sum() + ' (empty works too!)');
results.push(' sum(10) → ' + sum(10));
results.push('');
// 2. Regular parameter + rest
results.push('📌 Regular Parameter + Rest:\n');
function greet(greeting, ...names) {
return names.map(name => `${greeting}, ${name}!`);
}
results.push(' greet("Hello", "Alice", "Bob", "Charlie") →');
greet("Hello", "Alice", "Bob", "Charlie").forEach(line => {
results.push(' ' + line);
});
results.push('');
// 3. Multiply with rest
results.push('📌 Multiply with Rest:\n');
function multiply(multiplier, ...values) {
return values.map(value => multiplier * value);
}
results.push(' multiply(2, 1, 3, 4) → [' + multiply(2, 1, 3, 4).join(', ') + ']');
results.push(' multiply(10, 1, 2, 3) → [' + multiply(10, 1, 2, 3).join(', ') + ']');
results.push('');
// 4. Find max
results.push('📌 Find Maximum:\n');
function findMax(...numbers) {
return Math.max(...numbers);
}
results.push(' findMax(3, 1, 4, 1, 5, 9, 2, 6) → ' + findMax(3, 1, 4, 1, 5, 9, 2, 6));
results.push(' findMax(100, 50, 75) → ' + findMax(100, 50, 75));
results.push('');
// 5. Log all arguments
results.push('📌 Log All Arguments:\n');
function logAll(...args) {
return args.length + ' arguments: ' + args.join(', ');
}
results.push(' logAll("a", "b", "c") → ' + logAll("a", "b", "c"));
results.push(' logAll(1, 2, 3, 4, 5) → ' + logAll(1, 2, 3, 4, 5));
results.push('');
// 6. Combine with array
results.push('📌 Spread into Rest:\n');
const nums = [1, 2, 3, 4, 5];
results.push(' const nums = [1, 2, 3, 4, 5]');
results.push(' sum(...nums) → ' + sum(...nums));
results.push('');
// 7. Destructuring with rest
results.push('📌 Destructuring with Rest:\n');
const [first, second, ...rest] = [1, 2, 3, 4, 5];
results.push(' const [first, second, ...rest] = [1, 2, 3, 4, 5]');
results.push(' first → ' + first);
results.push(' second → ' + second);
results.push(' rest → [' + rest.join(', ') + ']');
results.push('');
// 8. Arrow function with rest
results.push('📌 Arrow Function with Rest:\n');
const sumArrow = (...nums) => nums.reduce((a, b) => a + b, 0);
results.push(' const sumArrow = (...nums) => nums.reduce((a, b) => a + b, 0);');
results.push(' sumArrow(1, 2, 3) → ' + sumArrow(1, 2, 3));
results.push('');
// 9. Practical: Build a string
results.push('📌 Practical: Join Words:\n');
function buildSentence(firstWord, ...restWords) {
return firstWord + ' ' + restWords.join(' ');
}
results.push(' buildSentence("Hello", "beautiful", "world") → "' +
buildSentence("Hello", "beautiful", "world") + '"');
results.push('');
// 10. Practical: tag function
results.push('📌 Practical: Formatting Function:\n');
function formatCurrency(currency, ...amounts) {
return amounts.map(amt => `${currency}${amt.toFixed(2)}`);
}
results.push(' formatCurrency("$", 10.5, 25, 99.99) → [' +
formatCurrency("$", 10.5, 25, 99.99).join(', ') + ']');
document.getElementById('output').textContent = results.join('\n');
// ============================================
// Interactive Functions
// ============================================
function getNumbers() {
const input = document.getElementById('numbersInput').value;
return input.split(',')
.map(n => Number(n.trim()))
.filter(n => !isNaN(n));
}
function runSum() {
const nums = getNumbers();
const result = sum(...nums);
showResult(`sum(${nums.join(', ')})`, result);
}
function runMax() {
const nums = getNumbers();
if (nums.length === 0) return showResult('findMax()', 'No numbers');
const result = Math.max(...nums);
showResult(`findMax(${nums.join(', ')})`, result);
}
function runMin() {
const nums = getNumbers();
if (nums.length === 0) return showResult('findMin()', 'No numbers');
const result = Math.min(...nums);
showResult(`findMin(${nums.join(', ')})`, result);
}
function runAverage() {
const nums = getNumbers();
if (nums.length === 0) return showResult('average()', 'No numbers');
const result = (sum(...nums) / nums.length).toFixed(2);
showResult(`average(${nums.join(', ')})`, result);
}
function runProduct() {
const nums = getNumbers();
if (nums.length === 0) return showResult('product()', 'No numbers');
const result = nums.reduce((a, b) => a * b, 1);
showResult(`product(${nums.join(', ')})`, result);
}
function showResult(expression, result) {
document.getElementById('resultDisplay').textContent = result;
document.getElementById('operationDetails').innerHTML =
`<p><code>${expression} → ${result}</code></p>`;
}
</script>
</body>
</html>
Quick Reference
Rest Parameter Rules
| Rule | Description |
|---|---|
| Must be last | Rest parameter must come after all regular parameters |
| Only one | Only one rest parameter per function |
| Real array | The rest parameter is a real array with all array methods |
| Named | You choose the name (e.g., ...args, ...numbers) |
Syntax
function fn(...rest) { } // Only rest
function fn(a, ...rest) { } // Regular + rest
function fn(a, b, ...rest) { } // Multiple regular + rest
const fn = (...rest) => { }; // Arrow function
// ❌ Invalid — rest must be last
// function fn(...rest, a) { }
// ❌ Invalid — only one rest
// function fn(...a, ...b) { }
Rest vs Spread
| Feature | Rest | Spread |
|---|---|---|
| Purpose | Collect arguments into array | Expand array into arguments |
| Where | Function parameters | Function calls, array literals |
| Syntax | function fn(...args) | fn(...arr) |
| Direction | Multiple → One array | One array → Multiple |
// Rest — collects
function sum(...nums) { return nums.reduce((a, b) => a + b, 0); }
// Spread — expands
const arr = [1, 2, 3];
sum(...arr); // 6
Rest vs arguments
| Aspect | Rest Parameters | arguments Object |
|---|---|---|
| Type | Real array | Array-like object |
| Array methods | ✅ Yes | ❌ No |
| Arrow functions | ✅ Yes | ❌ No |
| Named | ✅ Yes | ❌ No |
| Includes all args? | ❌ Only extras | ✅ All |
Best Practices
✅ Do This:
// Use rest parameters for variadic functions
function sum(...numbers) {
return numbers.reduce((a, b) => a + b, 0);
}
// Use descriptive names
function log(level, ...messages) { }
// Combine with regular parameters
function greet(greeting, ...names) { }
// Use with arrow functions
const max = (...nums) => Math.max(...nums);
// Use with destructuring
const [first, ...rest] = arr;
// Use spread to pass arrays
sum(...myArray);
❌ Don’t Do This:
// Don't put rest parameter in the middle
// function fn(...rest, a) { } // ❌ SyntaxError
// Don't use multiple rest parameters
// function fn(...a, ...b) { } // ❌ SyntaxError
// Don't use arguments in arrow functions
const fn = () => {
// console.log(arguments); // ❌ ReferenceError
};
// Don't rely on arguments for array methods
function oldSum() {
// arguments.reduce(...) // ❌ TypeError
return Array.from(arguments).reduce((a, b) => a + b, 0); // ✅
}
// Don't confuse rest with spread
function fn(...args) { } // Rest — collects
fn(...[1, 2, 3]); // Spread — expands
Common Pitfalls
| Pitfall | Problem | Solution |
|---|---|---|
| Rest not last | SyntaxError | Move rest to the end |
| Multiple rest params | SyntaxError | Use only one rest |
arguments in arrow | ReferenceError | Use rest parameters |
| Confusing with spread | Wrong behavior | Rest collects, spread expands |
| Expecting named params after rest | Not possible | Rest must be last |
Rest vs Spread — Visual
REST (Collect) SPREAD (Expand)
────────────── ───────────────
function sum(...nums) { } const arr = [1, 2, 3];
│ sum(...arr);
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ [1, 2, 3] │ │ 1, 2, 3 │
│ (one array) │ │ (expanded) │
└──────────────┘ └──────────────┘
Multiple → Array Array → Multiple
Pro Tip: Rest parameters are the modern way to handle variable arguments — they replace the old arguments object. Remember: rest collects (multiple → array), spread expands (array → multiple). Use rest parameters with any number of arguments to create flexible, variadic functions. They work with arrow functions, support array methods, and integrate beautifully with destructuring. The rules are simple: rest must be last, and only one per function. And don’t confuse ...args in a function definition (rest) with ...arr in a function call (spread) — same syntax, opposite directions!
Stop using slow, ad-bloated tool sites! 🤮
🔎 Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)
⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free
🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!