Signatur
Beschreibung
Mit dem Rest-Parameter kann eine Funktion beliebig viele Argumente entgegennehmen. Der letzte Parameter einer Funktionsdefinition wird mit drei Punkten (...) markiert. Alle Argumente, die nicht schon von den vorherigen, benannten Parametern belegt sind, landen in einem echten Array.
Im Vergleich zum älteren arguments-Objekt hat der Rest-Parameter mehrere Vorteile: Er ist ein richtiges Array, bei dem map(), filter(), reduce() und alle anderen Array-Methoden direkt zur Verfügung stehen. Er enthält nur die übrigen Argumente und nicht alle. Außerdem funktioniert er in Pfeilfunktionen, in denen es gar kein eigenes arguments gibt.
Typische Einsatzfälle sind Hilfsfunktionen wie sum(...zahlen), Logger mit einem festen Präfix und variablen Nachrichten, Wrapper- und Decorator-Funktionen, die Argumente unverändert weiterreichen, und das Destrukturieren mit Rest-Parameter wie function f(...[a, b]).
Die Syntax sieht genauso aus wie die Spread-Syntax, bewirkt aber das Gegenteil: Rest sammelt mehrere Werte in einem Array, während Spread ein Array in einzelne Werte auflöst.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $...restArgs | Array<any> | [] | Name des Rest-Parameters. Er enthält alle Argumente ab seiner Position als Array. Werden keine weiteren Argumente übergeben, ist er ein leeres Array ([]) und niemals undefined. |
| $a, b, … | any | Optionale benannte Parameter vor dem Rest-Parameter. Sie werden wie üblich der Reihe nach belegt. |
Rückgabewert
Array mit den übrigen Argumenten gebunden.Beispiele
Einfach: Summe beliebig vieler Zahlen
const sum = (...zahlen) => zahlen.reduce((acc, n) => acc + n, 0);
console.log(sum(1, 2, 3));
console.log(sum(10, 20, 30, 40));
console.log(sum());
Fester Parameter plus Rest: Logger mit Level
const log = (level, ...nachrichten) => {
const zeit = new Date().toISOString().slice(11, 19);
console.log(`[${zeit}] ${level.toUpperCase()}:`, ...nachrichten);
};
log('info', 'Server gestartet auf Port', 3000);
log('warn', 'Speicher knapp:', { freiMB: 128 });
Wrapper, der Argumente an eine andere Funktion weiterreicht
const mitZeitmessung = (fn) => async (...args) => {
const start = performance.now();
try {
return await fn(...args);
} finally {
console.log(`${fn.name} dauerte ${(performance.now() - start).toFixed(1)} ms`);
}
};
const ladeBenutzer = async (id, optionen = {}) => ({ id, ...optionen });
const gemessen = mitZeitmessung(ladeBenutzer);
const user = await gemessen(42, { detail: true });
console.log(user);
Rest-Parameter vs. arguments und Destrukturierung
function klassisch() {
// arguments ist kein echtes Array
return Array.isArray(arguments);
}
function modern(...args) {
return Array.isArray(args);
}
// Destrukturierung im Rest-Parameter
function punkt(...[x, y = 0]) {
return `(${x}|${y})`;
}
console.log(klassisch(1, 2));
console.log(modern(1, 2));
console.log(punkt(5));
console.log(modern.length);
// Wichtig · Fallstricke
- Nur einer und nur am Ende: Eine Funktion darf höchstens einen Rest-Parameter haben, und er muss der letzte Parameter sein.
function f(...a, b)ist einSyntaxError. Auch ein nachgestelltes Komma wie infunction f(...a,)ist nicht erlaubt. - Kein Standardwert:
function f(...args = [])ist ungültig. Das ist aber auch unnötig, denn ohne übrige Argumente ist der Rest-Parameter ohnehin ein leeres Array. Function.prototype.length: Der Rest-Parameter zählt nicht mit. Fürfunction f(a, ...b) {}ergibtf.lengthden Wert1.- Strict-Mode-Einschränkung: Eine Funktion mit Rest-, Standard- oder Destrukturierungs-Parametern darf im Funktionskörper kein
'use strict'enthalten. Das führt zu einemSyntaxError. - Kein
argumentsin Pfeilfunktionen: Pfeilfunktionen haben kein eigenesarguments. Dort ist der Rest-Parameter der richtige Weg. - Nicht mit Spread verwechseln: In der Parameterliste sammelt
...Werte (Rest), beim Aufruf verteilt es sie (Spread). - Leistung: Bei jedem Aufruf wird ein neues Array erzeugt. In extrem häufig aufgerufenem Code kann das messbar sein, im Normalfall spielt es keine Rolle.
- Kompatibilität: Wird seit ES2015 von allen modernen Browsern und von Node.js 6+ unterstützt. Nur für Internet Explorer ist eine Transpilierung (z. B. mit Babel) nötig.