Variadické funkce jsou užitečné v případech, kdy v definici funkce nechceme určovat přesný počet argumentů, které do ni budou předávány. Nebo pokud chceme zpracovat argumenty jako pole různé délky.
Uvnitř běžných funkcí jsou argumenty k dispozici prostřednictvím speciálního arguments
^mdn objektu.
Uvnitř funkce se vyskytuje jako lokální proměnná arguments
.
Tento objekt obsahuje všechny argumenty, které byly předány funkci a lze s ním do velké míry pracovat jako s normálním polem.
Jediné arrow funkce arguments
nemají.
Použití arguments jako s pole
Toto pseudo-pole však nemá všechny metody pole, jako jsou například "map" nebo "filter".
Lze jej však převést na pole pomocí některé ze funkcí slice()
, Array.from()
nebo spread operátoru.
const args = Array.prototype.slice.call(arguments);
// nebo
const args = Array.from(arguments);
// nebo
const args = [...arguments];
Například
function sum() {
let result = 0;
for (let i = 0; i < arguments.length; i++) {
result += arguments[i];
}
return result;
}
console.log(sum(1, 2, 3, 4, 5)); // 15
Na první pohled interface (signatura) těhle funkcí může budit zdání, že neakceptují žádný argument, což může být matoucí a některá IDE mohou nesprávně napovídat. Tenhle problém řeší rest parametry.
ES6 a rest parametr
Lze vytvořit variadickou funkci pomocí speciálního symbolu "...", který se nazývá "rest parameter". Rest parameter se používá jako poslední parametr funkce a představuje pole všech zbývajících argumentů, které nejsou explicitně deklarovány jako parametry funkce.
Například:
function sum(...a) {
let total = 0;
for (let i in a) {
total += a[i];
}
return total;
}
console.log(sum(1, 2, 3, 4, 5)); // 15
V tomto příkladu je funkce "sum" definována s rest parametrem "c". Výsledkem je součet všech argumentů.
Volání se spread operátorem
🤯 Malý tip na závěr: pomocí spread operátoru můžeme do funkce elegantně propašovat celé pole jako jednotlivé argumenty.
const pocet = [1, 2, 3, 4, 5];
console.log(sum(...pocet)); // 15
Uvědomte si však, že rest parametry a spread operátor sice v zápisu funkcích vypadá podobně, nicméně fakticky jsou to dvě různé operace. V jednom případě používáme rest parametr jako součást definice funkce a v druhém případě se používá spread operátor ve volání funkce.