|

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

RuleDescription
Must be lastThe rest parameter must be the last parameter in a function definition
Only oneOnly one rest parameter can be used per function
Collects extrasGathers all remaining arguments into an array
Array methodsThe rest parameter is a real array — you can use map, filter, reduce, etc.

Syntax

function functionName(param1, param2, ...restOfParams) {
    // ...
}
  • param1 and param2 — 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

AspectRest Parametersarguments Object
TypeReal arrayArray-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 versionES6 (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 CaseDescription
1Flexible functionsHandle any number of arguments
2Variadic functionsSimplify functions with variable parameters
3DestructuringSeparate 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:

  • numbers is an array containing all arguments
  • reduce() 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:

  • greeting gets the first argument ("Hello")
  • names collects 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:

  • multiplier gets the first argument (2)
  • values collects 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

RuleDescription
Must be lastRest parameter must come after all regular parameters
Only oneOnly one rest parameter per function
Real arrayThe rest parameter is a real array with all array methods
NamedYou 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

FeatureRestSpread
PurposeCollect arguments into arrayExpand array into arguments
WhereFunction parametersFunction calls, array literals
Syntaxfunction fn(...args)fn(...arr)
DirectionMultiple → One arrayOne 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

AspectRest Parametersarguments Object
TypeReal arrayArray-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

PitfallProblemSolution
Rest not lastSyntaxErrorMove rest to the end
Multiple rest paramsSyntaxErrorUse only one rest
arguments in arrowReferenceErrorUse rest parameters
Confusing with spreadWrong behaviorRest collects, spread expands
Expecting named params after restNot possibleRest 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!