possible duplicate of Is it possible to send a variable number of arguments to a JavaScript function? related / possible duplicate of stackoverflow.com/questions/4633125/… @Luke no, it's not.
A function that receives variable number of arguments should use va_arg() to extract arguments from the variable argument list.
Except for functions with variable-length argument lists, the number of arguments in a function call must be the same as the number of parameters in the function definition. This number can be zero. The maximum number of arguments (and corresponding parameters) is 253 for a single function.
Update: Since ES6, you can simply use the spread syntax when calling the function:
func(...arr);
Since ES6 also if you expect to treat your arguments as an array, you can also use the spread syntax in the parameter list, for example:
function func(...args) {
args.forEach(arg => console.log(arg))
}
const values = ['a', 'b', 'c']
func(...values)
func(1, 2, 3)
And you can combine it with normal parameters, for example if you want to receive the first two arguments separately and the rest as an array:
function func(first, second, ...theRest) {
//...
}
And maybe is useful to you, that you can know how many arguments a function expects:
var test = function (one, two, three) {};
test.length == 3;
But anyway you can pass an arbitrary number of arguments...
The spread syntax is shorter and "sweeter" than apply
and if you don't need to set the this
value in the function call, this is the way to go.
Here is an apply example, which was the former way to do it:
var arr = ['a','b','c'];
function func() {
console.log(this); // 'test'
console.log(arguments.length); // 3
for(var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
};
func.apply('test', arr);
Nowadays I only recommend using apply
only if you need to pass an arbitrary number of arguments from an array and set the this
value. apply
takes is the this
value as the first arguments, which will be used on the function invocation, if we use null
in non-strict code, the this
keyword will refer to the Global object (window) inside func
, in strict mode, when explicitly using 'use strict' or in ES modules, null
will be used.
Also note that the arguments
object is not really an Array, you can convert it by:
var argsArray = Array.prototype.slice.call(arguments);
And in ES6:
const argsArray = [...arguments] // or Array.from(arguments)
But you rarely use the arguments
object directly nowadays thanks to the spread syntax.
You can actually pass as many values as you want to any javascript function. The explicitly named parameters will get the first few values, but ALL parameters will be stored in the arguments array.
To pass the arguments array in "unpacked" form, you can use apply, like so (c.f. Functional Javascript):
var otherFunc = function() {
alert(arguments.length); // Outputs: 10
}
var myFunc = function() {
alert(arguments.length); // Outputs: 10
otherFunc.apply(this, arguments);
}
myFunc(1,2,3,4,5,6,7,8,9,10);
The splat and spread operators are part of ES6, the planned next version of Javascript. So far only Firefox supports them. This code works in FF16+:
var arr = ['quick', 'brown', 'lazy'];
var sprintf = function(str, ...args)
{
for (arg of args) {
str = str.replace(/%s/, arg);
}
return str;
}
sprintf.apply(null, ['The %s %s fox jumps over the %s dog.', ...arr]);
sprintf('The %s %s fox jumps over the %s dog.', 'slow', 'red', 'sleeping');
Note the awkard syntax for spread. The usual syntax of sprintf('The %s %s fox jumps over the %s dog.', ...arr);
is not yet supported. You can find an ES6 compatibility table here.
Note also the use of for...of
, another ES6 addition. Using for...in
for arrays is a bad idea.
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.
The apply
function takes two arguments; the object this
will be binded to, and the arguments, represented with an array.
some_func = function (a, b) { return b }
some_func.apply(obj, ["arguments", "are", "here"])
// "are"
It's called the splat
operator. You can do it in JavaScript using apply
:
var arr = ['a','b','c','d'];
var func = function() {
// debug
console.log(arguments.length);
console.log(arguments);
}
func('a','b','c','d'); // prints 4 which is what I want, then 'a','b','c','d'
func(arr); // prints 1, then 'Array'
func.apply(null, arr);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With