JavaScript variable number of arguments to function

425,816

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

  1. It is an array, and not an object like arguments. This allows you to apply functions like map or sort directly.
  2. 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
Share:
425,816
Timo
Author by

Timo

Updated on July 08, 2022

Comments

  • Timo
    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)
    
  • Neil
    Neil almost 12 years
    +1. Nice trick. Saves a lot of boiler plate to have every parameter defined, default or otherwise.
  • Jonas Schubert Erlandsson
    Jonas Schubert Erlandsson over 11 years
    This would be better since it removes the coupling to argument order. Loosely coupled interfaces are good standard practice...
  • mbeasley
    mbeasley over 11 years
    Underscore's _.defaults() method is a very nice alternative to merge specified and default arguments.
  • Johan Hoeksma
    Johan Hoeksma almost 11 years
    Tnx. It is great for parsing Strings from android native code to javascript in a Webview.
  • rvighne
    rvighne over 10 years
    Sure, 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
    Nate C-K over 10 years
    This is also nice because if you want, you can build the context argument with code and pass it around before it gets used.
  • User2
    User2 about 10 years
    This solution worked best for me. Thanks. Further information on the arguments keyword HERE.
  • mcurland
    mcurland almost 10 years
    Agreed, 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
    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
    Dmytro Medvid over 8 years
    nice solution to convert arguments to array. It was helpful for me today.
  • Stijn de Witt
    Stijn de Witt over 7 years
    Interestingly, 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 the arguments object. Knowing this, and that the method concat returns a copy of the 'array' it's called on, we can easily convert the arguments object to a real array like this: var args = [].concat.call(arguments). Some people prefer to use Array.prototype.concat.call instead, but I like the [], they are short and sweet!
  • tanguy_k
    tanguy_k over 7 years
    FYI it is called "the rest parameter syntax": developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • anhldbk
    anhldbk almost 7 years
    This approach does NOT work well with arrow functions. You could use the approach of Ramast (below)
  • David Gatti
    David Gatti almost 7 years
    Deprecated 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
    roufamatic almost 7 years
    @DavidGatti It looks like using Function.arguments is deprecated, but not the vanilla arguments object. See developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… .
  • haxpor
    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
    David Gatti almost 7 years
    What do you understand by vanilla? I still see a thumb down next to it.
  • roufamatic
    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
    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
    Stijn de Witt about 6 years
    Looks 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 using call is that concat will be invoked with arguments as it's this. So it will clone the arguments object to a real array.
  • Roee Gavirel
    Roee Gavirel over 5 years
    Keep in mind that according to developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… it's not supported on IE.
  • Brian Burns
    Brian Burns about 5 years
    Here's a table showing browser support - caniuse.com/#feat=rest-parameters
  • Yasir Jan
    Yasir Jan about 5 years
    I wish I could do arguments.join().
  • Willian Andrade
    Willian Andrade almost 5 years
    @YasirJan use [...arguments].join()
  • Ashish
    Ashish almost 5 years
    Such a nice answer!
  • Marcin Wojnarski
    Marcin Wojnarski almost 3 years
    Worth to note that z='d' syntax does NOT assign to an argument named z (as it would do, say, in Python), but instead passes an unnamed argument value 'd' and creates a local variable z with this same value as a side effect.