JS: functions arguments default values

2020-03-01 20:34发布

问题:

In some languages you can set default values for function's arguments:

function Foo(arg1 = 50, arg2 = 'default') {
    //...
}

How do you do it in JavaScript?

回答1:

In JavaScript, anything that isn't set is given the value undefined. This means that if you want to set default values for a function, your first line needs to be a check to see if those values aren't defined:

function Foo(arg1, arg2) {
    if (typeof(arg1) === "undefined") { arg1 = 50; }
    if (typeof(arg2) === "undefined") { arg2 = "default"; }
}

You can take a bit of a short cut if you know roughly what those values will be:

function Foo(arg1, arg2) {
    arg1 = arg1 || 50;
    arg2 = arg2 || "default";
}

However, if those arguments are falsy, they'll be replaced. This means that if arg1 is an empty string, null, undefined, false or 0 it'll be changed to 50, so be careful if you chose to use it



回答2:

I prefer the == null check instead of typeof(arg1) === undefined (as the jQuery library does internally: http://docs.jquery.com/JQuery_Core_Style_Guidelines#JSLint). Not only is it more concise, it also handles both null and undefined, so that client code can pass in null and get the default applied.

It is also possible to wrap the function in another function that supplies defaults. The prototypejs library has a function that supplies the argumentNames() (or if you don't want to use prototype, you can just borrow the implementation -- it's just a regex applied against the results of the function's toString()).

So you could do something like this:

var Foo = defaults(Foo, { arg1: 50, arg2: 'default' });
function Foo(arg1, arg2) {
  //...
}

And the implementation of defaults() would look something like this:

function defaults(fn, def) {
  return function() {
    var arg_names = fn.argumentNames();
    var nArgs = args.length;
    for (var nArg = 0; nArg < nArgs; ++nArg) {
      if (arguments[nArg] == null && arg_names[nArg] in def)
        arguments[nArg] = def[arg_names[nArg]];
    }
    fn.apply(this, arguments);
  }
}

Of course, that's untested code and the way it's written, it requires the Prototype library. But all that said, the == null approach inside the function is more natural to Javascript, is easier to debug (you don't have another function layer to step through), and I find it easier to read:

function Foo(arg1, arg2) {
  if (arg1 == null) arg1 = 50;
  if (arg2 == null) arg2 = 'default';
}


回答3:

You would have to do it in the function body:

function Foo(arg1 ,arg2) {
    if( typeof arg1 === 'undefined' )
        arg1 = 50;

    if( typeof arg2 === 'undefined' )
        arg2 = 'default';
    //...
}

Another way to test them for undefined or null is like this:

function Foo(arg1 ,arg2) {
    if( arg1 == undefined )
        arg1 = 50;

    if( arg2 == undefined )
        arg2 = 'default';
    //...
}

Some people don't like it because it is possible to override the value of undefined since it is just a global property. As long as it isn't overridden, this would work fine. If the parameters are null or undefined, they'll be set to a default.



回答4:

As of ES2015 (ES6), default parameters can be set like so:

function multiply (a, b = 2) {
  return a * b;
}
multiply(5); // 10