JavaScript variable number of arguments to functio

2018-12-31 05:43发布

Is there a way to allow "unlimited" vars for a function in JavaScript?

Example:

load(var1, var2, var3, var4, var5, etc...)
load(var1)

11条回答
深知你不懂我心
2楼-- · 2018-12-31 06:39

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.

查看更多
还给你的自由
3楼-- · 2018-12-31 06:40

In 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);
}
查看更多
人间绝色
4楼-- · 2018-12-31 06:43

As mentioned already, you can use the arguments object to retrieve a variable number of function parameters.

If you want to call another function with the same arguments, use apply. You can even add or remove arguments by converting arguments to an array. For example, this function inserts some text before logging to console:

log() {
    let args = Array.prototype.slice.call(arguments);
    args = ['MyObjectName', this.id_].concat(args);
    console.log.apply(console, args);
}
查看更多
看淡一切
5楼-- · 2018-12-31 06:48

Although I generally agree that the named arguments approach is useful and flexible (unless you care about the order, in which case arguments is easiest), I do have concerns about the cost of the mbeasley approach (using defaults and extends). This is an extreme amount of cost to take for pulling default values. First, the defaults are defined inside the function, so they are repopulated on every call. Second, you can easily read out the named values and set the defaults at the same time using ||. There is no need to create and merge yet another new object to get this information.

function load(context) {
   var parameter1 = context.parameter1 || defaultValue1,
       parameter2 = context.parameter2 || defaultValue2;

   // do stuff
}

This is roughly the same amount of code (maybe slightly more), but should be a fraction of the runtime cost.

查看更多
步步皆殇っ
6楼-- · 2018-12-31 06:48

While @roufamatic did show use of the arguments keyword and @Ken showed a great example of an object for usage I feel neither truly addressed what is going on in this instance and may confuse future readers or instill a bad practice as not explicitly stating a function/method is intended to take a variable amount of arguments/parameters.

function varyArg () {
    return arguments[0] + arguments[1];
}

When another developer is looking through your code is it very easy to assume this function does not take parameters. Especially if that developer is not privy to the arguments keyword. Because of this it is a good idea to follow a style guideline and be consistent. I will be using Google's for all examples.

Let's explicitly state the same function has variable parameters:

function varyArg (var_args) {
    return arguments[0] + arguments[1];
}

Object parameter VS var_args

There may be times when an object is needed as it is the only approved and considered best practice method of an data map. Associative arrays are frowned upon and discouraged.

SIDENOTE: The arguments keyword actually returns back an object using numbers as the key. The prototypal inheritance is also the object family. See end of answer for proper array usage in JS

In this case we can explicitly state this also. Note: this naming convention is not provided by Google but is an example of explicit declaration of a param's type. This is important if you are looking to create a more strict typed pattern in your code.

function varyArg (args_obj) {
    return args_obj.name+" "+args_obj.weight;
}
varyArg({name: "Brian", weight: 150});

Which one to choose?

This depends on your function's and program's needs. If for instance you are simply looking to return a value base on an iterative process across all arguments passed then most certainly stick with the arguments keyword. If you need definition to your arguments and mapping of the data then the object method is the way to go. Let's look at two examples and then we're done!

Arguments usage

function sumOfAll (var_args) {
    return arguments.reduce(function(a, b) {
        return a + b;
    }, 0);
}
sumOfAll(1,2,3); // returns 6

Object usage

function myObjArgs(args_obj) {
    // MAKE SURE ARGUMENT IS AN OBJECT OR ELSE RETURN
    if (typeof args_obj !== "object") {
        return "Arguments passed must be in object form!";
    }

    return "Hello "+args_obj.name+" I see you're "+args_obj.age+" years old.";
}
myObjArgs({name: "Brian", age: 31}); // returns 'Hello Brian I see you're 31 years old

Accessing an array instead of an object ("...args" The rest parameter)

As mentioned up top of the answer the arguments keyword actually returns an object. Because of this any method you want to use for an array will have to be called. An example of this:

Array.prototype.map.call(arguments, function (val, idx, arr) {});

To avoid this use the rest parameter:

function varyArgArr (...var_args) {
    return var_args.sort();
}
varyArgArr(5,1,3); // returns 1, 3, 5
查看更多
登录 后发表回答