34

Question

What is a good way of assigning a default value to an optional parameter?

Background

I'm playing around with optional parameters in JavaScript, and the idea of assigning a default value if a parameter is not specified. My method in question accepts two parameters, the latter of which I deem to be optional, and if unspecified should default to false. My method looks something like this...

// selects the item, appropriately updating any siblings
// item to select [, toggle on / off]
this.selectItem = function(item, toggle)
{
    toggle = toggle && typeof toggle === 'boolean';
    if (toggle)
    {
       // ...
    }
}

Testing

After running a few tests on this jsFiddle, using the following principal for default value assigning:

function checkParamIsBoolean(param)
{
    param = param && typeof param === 'boolean';
}

checkParamIsBoolean('me'); // boolean
checkParamIsBoolean([]); // boolean
checkParamIsBoolean(true); // boolean
checkParamIsBoolean(false); // boolean
checkParamIsBoolean(1 == 1); // boolean
checkParamIsBoolean(1); // boolean
checkParamIsBoolean(null); // object
checkParamIsBoolean(undefined); // undefined
​

As you can, the results vary, and aren't desired.

Expected

null = false
undefined = false

Actual

null = object
undefined = undefined

Summary

Are there any alternative approaches to assigning a default value to an optional parameter if it's unspecified; would it be better to use _toggle as the parameter and then assign the value to var toggle within the method?

Richard
  • 8,110
  • 3
  • 36
  • 59
  • 3
    There are many related questions about this topic already ([example](http://stackoverflow.com/questions/148901/is-there-a-better-way-to-do-optional-function-parameters-in-javascript)). Have a look at all the ones on the right side. If you ask why you don't get the expected outcome, this is because `null` and `undefined` are falsy and boolean operators return the value of the variable that determines the outcome of the expression. – Felix Kling Jun 14 '12 at 09:17
  • You say that you want to use default value for optional parameter, and yet only the last call to the `checkParamIsBoolean` is not setting the parameter. All the other calls, even when you use null as the argument, is setting a value for the parameter. – Simon Forsberg Jun 14 '12 at 09:26
  • In addition to Felix' comment I would like to add that `null` is a value of the type object. Specifying `null` as an argument is not the same as an unspecified argument. Btw, another way to call the method is `checkParamIsBoolean();` (this is basically the same as your last example) – Simon Forsberg Jun 14 '12 at 09:32

9 Answers9

25

Better solution is to use named arguments wraped in a object. It keeps your code clean and prevents errors in case of complex functions (with many default and non-default arguments). Otherwise you need to remember about the order of arguments and assign default values based on the types of arguments present (that's what you're trying to do).

That method is a primary way of passing params jQuery and jQuery's plugins.

function test(options) { 

  // set up default options 
  var defaults = { 
    param1:      'test', 
    param2:      100
  }; 

  // combine options with default values
  var options = $.extend({}, defaults, options); // If you're not using jQuery you need different function here

  alert(options.param1)
  alert(options.param2)

}

test({'param2': 200}) // Call the function with just the second param
Mariusz Jamro
  • 30,615
  • 24
  • 120
  • 162
  • You do have a good point there. However, I think it's often easier to learn the orders of arguments than to learn the names of the arguments, which you need to know in this case. (The big exception is PHP's needles and haystacks which I have problems remembering the order of). – Simon Forsberg Jun 14 '12 at 11:07
  • 9
    I don't know if I am the only one, but when the Comment "If You are not using Jquery..." started to scroll off the screen, I was fully expecting to read "... You are doing it wrong." when I scrolled over. – JHixson May 22 '13 at 20:13
  • 3
    I am sure that @JHixson just thought it was funny. Dang. – Scott Adams Aug 05 '13 at 15:01
  • 1
    @Secator Indeed, It just gave me a chuckle =) – JHixson Aug 05 '13 at 21:24
14

You can use this construction for optional parameters in your code:

//...
optionalParam = optionalParam || 'some default value';

In your concrete exaple it would be something like this:

this.selectItem = function(item, toggle)
{
    toggle = toggle || false;
   // ...
}

But in your case you could use toogle (optional parameter) directly in if statement (since you only want to check for its existence. Or optionally you could enforce boolean value like this toogle = !!toogle (double negation).

sbgoran
  • 3,451
  • 2
  • 19
  • 30
  • 1
    what if I want true as default value and my parameter is false then I will get true – Thomas Mar 16 '17 at 16:41
  • 1
    @Thomas Then you could use construction like this perhaps: `toggle = (arguments.length < 2) || toggle;`. Anyhow all this "shortcuts" in JS should be used carefully and with clear picture of all possible consequences (I guess that is why [default parameters](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Default_parameters) are introduced in ES6 :)) – sbgoran Mar 17 '17 at 08:35
4

A very simple way to check if toggle is undefined, and if it is then set a default value:

if (toggle === undefined) toggle = "<your default value>";

Note that this does not change toggle if it is specified but of another type than what you expected.

Simon Forsberg
  • 13,086
  • 10
  • 64
  • 108
2

Try it the other way around:

param = typeof param === 'boolean' && param;

This will make sure all are a boolean, see this fiddle

floorish
  • 706
  • 6
  • 18
1

Why do you check the parameter to be boolean, if you expect an other result? The usual way would be checking for typeof toggle != "undefined", but in your case

toggle = Boolean(toggle);

should do the task. You can also use the shortcut !!toggle, or use it directly in the if-clause:

if (toggle) { // will evaluate to "false" for undefined
    ...

BTW, no need for a _toggle parameter; you can just reassign to toggle.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
1

You can replace

param = param && typeof param === 'boolean';

with

param = !!(param && typeof param === 'boolean');

This will convert the result of the statement to the boolean negate, and then negate it back again.

Niclas Sahlin
  • 1,125
  • 9
  • 15
1

If you consider null(as well as no args passed), undefined and ""(empty string) as "not an argument has passed to my function" use this statement:

toggle = toggle&&toggle||default_value

Now if you pass null, undefined or "" to your function as toggle arg, this line fills it with default_value.

Sepehr
  • 2,051
  • 19
  • 29
0

Take a look at jQuery extend and how they handle optional parameters.

Anthony
  • 12,177
  • 9
  • 69
  • 105
0

It can easilly be done with ArgueJS:

this.selectItem = function()
{
  arguments = __({item: undefined, toggle: [Boolean, false})
  if (arguments.toggle)
  {
     // ...
  }
}

You can also check the type of item by changing undefined by the desired type.

zVictor
  • 3,610
  • 3
  • 41
  • 56