There are two methods as of ES2015.
arguments
ObjectThis object is built into functions, and it refers to, appropriately, the arguments of a function. It is not technically an array, though, so typical array operations won't work on it. The suggested method is to use Array.from
or the spread operator to create an array from it.
I've seen other answers mention using slice
. Don't do that. It prevents optimizations (source: MDN).
Array.from(arguments)
[...arguments]
However, I would argue that arguments
is problematic because it hides what a function accepts as input. An arguments
function typically is written like this:
function mean(){
let args = [...arguments];
return args.reduce((a,b)=>a+b) / args.length;
}
Sometimes, the function header is written like the following to document the arguments in a C-like fashion:
function mean(/* ... */){ ... }
But that is rare.
As for why it is problematic, take C, for example. C is backwards compatible with an ancient pre-ANSI dialect of the language known as K&R C. K&R C allows function prototypes to have an empty arguments list.
int myFunction();
/* This function accepts unspecified parameters */
ANSI C provides a facility for varargs
(...
), and void
to specify an empty arguments-list.
int myFunction(void);
/* This function accepts no parameters */
Many people inadvertently declare functions with an unspecified
arguments list (int myfunction();
), when they expect the function to take zero arguments. This is technically a bug because the function will accept arguments. Any number of them.
A proper varargs
function in C takes the form:
int myFunction(int nargs, ...);
And JavaScript actually does have something similar to this.
I've already shown you the spread operator, actually.
...name
It's pretty versatile, and can also be used in a function's argument-list ("rest parameters") to specify varargs in a nicely documented fashion:
function mean(...args){
return args.reduce((a,b)=>a+b) / args.length;
}
Or as a lambda expression:
((...args)=>args.reduce((a,b)=>a+b) / args.length)(1,2,3,4,5); // 3
I much prefer the spread operator. It is clean and self-documenting.