Funkce s variabilním počtem argumentů

AndreaAndrea

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.