JavaScript variable number of arguments to function
Solution 1
Sure, just use the arguments
object.
function foo() {
for (var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
Solution 2
In (most) recent browsers, you can accept variable number of arguments with this syntax:
function my_log(...args) {
// args is an Array
console.log(args);
// You can pass this array as parameters to another function
console.log(...args);
}
Here's a small example:
function foo(x, ...args) {
console.log(x, args, ...args, arguments);
}
foo('a', 'b', 'c', z='d')
=>
a
Array(3) [ "b", "c", "d" ]
b c d
Arguments
0: "a"
1: "b"
2: "c"
3: "d"
length: 4
Documentation and more examples here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters
Solution 3
Another option is to pass in your arguments in a context object.
function load(context)
{
// do whatever with context.name, context.address, etc
}
and use it like this
load({name:'Ken',address:'secret',unused:true})
This has the advantage that you can add as many named arguments as you want, and the function can use them (or not) as it sees fit.
Solution 4
I agree with Ken's answer as being the most dynamic and I like to take it a step further. If it's a function that you call multiple times with different arguments - I use Ken's design but then add default values:
function load(context) {
var defaults = {
parameter1: defaultValue1,
parameter2: defaultValue2,
...
};
var context = extend(defaults, context);
// do stuff
}
This way, if you have many parameters but don't necessarily need to set them with each call to the function, you can simply specify the non-defaults. For the extend method, you can use jQuery's extend method ($.extend()
), craft your own or use the following:
function extend() {
for (var i = 1; i < arguments.length; i++)
for (var key in arguments[i])
if (arguments[i].hasOwnProperty(key))
arguments[0][key] = arguments[i][key];
return arguments[0];
}
This will merge the context object with the defaults and fill in any undefined values in your object with the defaults.
Solution 5
It is preferable to use rest parameter syntax as Ramast pointed out.
function (a, b, ...args) {}
I just want to add some nice property of the ...args argument
- It is an array, and not an object like arguments. This allows you to apply functions like map or sort directly.
- It does not include all parameters but only the one passed from it on. E.g. function (a, b, ...args) in this case args contains argument 3 to arguments.length
Timo
Updated on July 08, 2022Comments
-
Timo almost 2 years
Is there a way to allow "unlimited" vars for a function in JavaScript?
Example:
load(var1, var2, var3, var4, var5, etc...) load(var1)
-
Nakilon over 11 yearspossible duplicate of Is it possible to send a variable number of arguments to a JavaScript function?
-
Luke about 9 yearsrelated / possible duplicate of stackoverflow.com/questions/4633125/…
-
Scruffy over 7 years@Luke no, it's not. That question asks how to call a function with an arbitrary number of arguments with the arguments in an array. This asks how to handle such a call.
-
gschenk over 4 yearsFor easier searching, such a function is called a 'variadic function'.
-
-
Neil almost 12 years+1. Nice trick. Saves a lot of boiler plate to have every parameter defined, default or otherwise.
-
Jonas Schubert Erlandsson over 11 yearsThis would be better since it removes the coupling to argument order. Loosely coupled interfaces are good standard practice...
-
mbeasley over 11 yearsUnderscore's
_.defaults()
method is a very nice alternative to merge specified and default arguments. -
Johan Hoeksma almost 11 yearsTnx. It is great for parsing Strings from android native code to javascript in a Webview.
-
rvighne over 10 yearsSure, that's better in some cases. But let's say the individual arguments don't really relate to one another, or are all supposed to have equal meaning (like array elements). Then OP's way is best.
-
Nate C-K over 10 yearsThis is also nice because if you want, you can build the
context
argument with code and pass it around before it gets used. -
User2 about 10 yearsThis solution worked best for me. Thanks. Further information on the arguments keyword HERE.
-
mcurland almost 10 yearsAgreed, although the harm depends on the type of value or default itself. Otherwise,
(parameter1=context.parameter1)===undefined && (parameter1=defaultValue1)
or for less code volume a small helper function like:function def(providedValue, default) {return providedValue !== undefined ? providedValue : defaultValue;} var parameter1 = def(context.parameter1, defaultValue1)
provide alternate patterns. However, my point still stands: creating extra objects for every function invocation and running expensive loops to set a couple of default values is a crazy amount of overhead. -
Luke about 9 years
arguments
is a special "Array-like" object, which means it has has a length, but no other array functions. See developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… for more information, and this answer: stackoverflow.com/a/13145228/1766230 -
Dmytro Medvid over 8 yearsnice solution to convert arguments to array. It was helpful for me today.
-
Stijn de Witt over 7 yearsInterestingly, the Array methods in Javascript have been defined in such a way that they work on any object that has a
length
property. This includes thearguments
object. Knowing this, and that the methodconcat
returns a copy of the 'array' it's called on, we can easily convert thearguments
object to a real array like this:var args = [].concat.call(arguments)
. Some people prefer to useArray.prototype.concat.call
instead, but I like the[]
, they are short and sweet! -
tanguy_k over 7 yearsFYI it is called "the rest parameter syntax": developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
-
anhldbk almost 7 yearsThis approach does NOT work well with arrow functions. You could use the approach of Ramast (below)
-
David Gatti almost 7 yearsDeprecated This feature has been removed from the Web standards. Though some browsers may still support it, it is in the process of being dropped. Avoid using it and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.
-
roufamatic almost 7 years@DavidGatti It looks like using
Function.arguments
is deprecated, but not the vanillaarguments
object. See developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… . -
haxpor almost 7 years+1 This is elegant and clean solution. Especially suitable for passing through long list of parameters into another function call, and with possible that those variable parameters are at arbitrary position.
-
David Gatti almost 7 yearsWhat do you understand by vanilla? I still see a thumb down next to it.
-
roufamatic almost 7 years@DavidGatti From the text below the thumb down: "This is deprecated as property of Function. Use the arguments object available within the function instead."
-
Admin about 6 years@StijndeWitt: When I try what you suggest, I get a single-element array whose element is a hash with keys "0", "1", ...
-
Stijn de Witt about 6 yearsLooks like you are adding the arguments object to the array. Make sure to use
call
to invoke the concat function. If you invoke it directly the object will be added. The trick with usingcall
is thatconcat
will be invoked witharguments
as it'sthis
. So it will clone the arguments object to a real array. -
Roee Gavirel over 5 yearsKeep in mind that according to developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… it's not supported on IE.
-
Brian Burns about 5 yearsHere's a table showing browser support - caniuse.com/#feat=rest-parameters
-
Yasir Jan about 5 yearsI wish I could do arguments.join().
-
Willian Andrade almost 5 years@YasirJan use
[...arguments].join()
-
Ashish almost 5 yearsSuch a nice answer!
-
Marcin Wojnarski almost 3 yearsWorth to note that
z='d'
syntax does NOT assign to an argument namedz
(as it would do, say, in Python), but instead passes an unnamed argument value'd'
and creates a local variablez
with this same value as a side effect.