Is there a better way to do optional function parameters in JavaScript? [duplicate]

Is there a better way to do optional function parameters in JavaScript? [duplicate]

This question already has an answer here:

Set a default parameter value for a JavaScript function

23 answers

I’ve always handled optional parameters in JavaScript like this:
function myFunc(requiredArg, optionalArg){
optionalArg = optionalArg || ‘defaultValue’;

// Do stuff
}

Is there a better way to do it?
Are there any cases where using || like that is going to fail?

Solutions/Answers:

Solution 1:

Your logic fails if optionalArg is passed, but evaluates as false – try this as an alternative

if (typeof optionalArg === 'undefined') { optionalArg = 'default'; }

Or an alternative idiom:

optionalArg = (typeof optionalArg === 'undefined') ? 'default' : optionalArg;

Use whichever idiom communicates the intent best to you!

Solution 2:

In ECMAScript 2015 (aka “ES6”) you can declare default argument values in the function declaration:

function myFunc(requiredArg, optionalArg = 'defaultValue') {
    // do stuff
}

More about them in this article on MDN.

This is currently only supported by Firefox, but as the standard has been completed, expect support to improve rapidly.

EDIT (2019-06-12):

Default parameters are now widely supported by modern browsers. All versions of Internet Explorer do not support this feature. However, Chrome, Firefox, and Edge currently support it.

Solution 3:

I find this to be the simplest, most readable way:

if (typeof myVariable === 'undefined') { myVariable = 'default'; }
//use myVariable here

Paul Dixon’s answer (in my humble opinion) is less readable than this, but it comes down to preference.

insin’s answer is much more advanced, but much more useful for big functions!

EDIT 11/17/2013 9:33pm: I’ve created a package for Node.js that makes it easier to “overload” functions (methods) called parametric.

Solution 4:

If you need to chuck a literal NULL in, then you could have some issues. Apart from that, no, I think you’re probably on the right track.

The other method some people choose is taking an assoc array of variables iterating through the argument list. It looks a bit neater but I imagine it’s a little (very little) bit more process/memory intensive.

function myFunction (argArray) {
    var defaults = {
        'arg1'  :   "value 1",
        'arg2'  :   "value 2",
        'arg3'  :   "value 3",
        'arg4'  :   "value 4"
    }

    for(var i in defaults) 
        if(typeof argArray[i] == "undefined") 
               argArray[i] = defaults[i];

    // ...
}

Solution 5:

Ideally, you would refactor to pass an object and merge it with a default object, so the order in which arguments are passed doesn’t matter (see the second section of this answer, below).

If, however, you just want something quick, reliable, easy to use and not bulky, try this:


A clean quick fix for any number of default arguments

  • It scales elegantly: minimal extra code for each new default
  • You can paste it anywhere: just change the number of required args and variables
  • If you want to pass undefined to an argument with a default value, this way, the variable is set as undefined. Most other options on this page would replace undefined with the default value.

Here’s an example for providing defaults for three optional arguments (with two required arguments)

function myFunc( requiredA, requiredB,  optionalA, optionalB, optionalC ) {

  switch (arguments.length - 2) { // 2 is the number of required arguments
    case 0:  optionalA = 'Some default';
    case 1:  optionalB = 'Another default';
    case 2:  optionalC = 'Some other default';
    // no breaks between cases: each case implies the next cases are also needed
  }

}

Simple demo. This is similar to roenving’s answer, but easily extendible for any number of default arguments, easier to update, and using arguments not Function.arguments.


Passing and merging objects for more flexibility

The above code, like many ways of doing default arguments, can’t pass arguments out of sequence, e.g., passing optionalC but leaving optionalB to fall back to its default.

A good option for that is to pass objects and merge with a default object. This is also good for maintainability (just take care to keep your code readable, so future collaborators won’t be left guessing about the possible contents of the objects you pass around).

Example using jQuery. If you don’t use jQuery, you could instead use Underscore’s _.defaults(object, defaults) or browse these options:

function myFunc( args ) {
  var defaults = {
    optionalA: 'Some default',
    optionalB: 'Another default',
    optionalC: 'Some other default'
  };
  args = $.extend({}, defaults, args);
}

Here’s a simple example of it in action.

Solution 6:

You can use some different schemes for that. I’ve always tested for arguments.length:

function myFunc(requiredArg, optionalArg){
  optionalArg = myFunc.arguments.length<2 ? 'defaultValue' : optionalArg;

  ...

— doing so, it can’t possibly fail, but I don’t know if your way has any chance of failing, just now I can’t think up a scenario, where it actually would fail …

And then Paul provided one failing scenario !-)