user824294 user824294 - 2 months ago 12
Javascript Question

Javascript: "Infinite" parameters for function?

In Chrome, when I type

console.log
in the one below:

console.log("A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter");


...it prints it correctly, with no errors or warnings. I appended more parameters, but it still prints it out correctly.

console.log("A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter", "A parameter");


How can I have an "infinite" parameter function just like that one?

Answer

Functions can access an array-like object called arguments that contains all the arguments that they received

function print_my_arguments(/**/){
    var args = arguments;
    for(var i=0; i<args.length; i++){
        console.log(args[i]);
    }
};

And you can do the opposite conversion (call a function given a list of arguments) with the apply method:

// These are equivalent:
print_my_arguments(1,2,3);
print_my_arguments.apply(null, [1,2,3]);

// The first parameter to `apply` is the `this`.
// It is used when the function is a method.
foo.bar(1,2,3);
var f = foo.bar; f.apply(foo, [1,2,3]);

Some important points to note:

  1. arguments isn't an actual array and it has none of the usual array methods (slice, join, etc). You can convert it to an array with the following line:

    var args = Array.prototype.slice.call(arguments);
    
  2. Slice is also useful if you don't want to exclude the named function parameters from the arguments array:

    function foo(first_arg, second_arg /**/){
        var variadic_args = Array.prototype.slice.call(arguments, 2);
    }
    
  3. Not every browser can handle an arbitrarily large number of function parameters. Last time I tested this, in Chrome and IE there was a stackoverflow after some 200.000 arguments. In this cases, use a regular array instead of variadic parameters.

  4. Those /**/ comments I wrote on my arguments lists are nor mandatory. They are a coding a convention that I use to mark my variadic functions and differentiate them from regular functions, which never access the their arguments object.

    // If you have a quick look at this function you might think
    // that it takes zero parameters.
    function foo(){
        console.log(arguments.length);
    }