10

I am doing a lot of front-end development and I see myself doing this a lot:

function doSomething(arg){
    var int = arg ? arg : 400
    //some code after
}

So I was wondering if the was a way to do this, but shorter and cleaner (I don't like to see arg twice in the same line).

I've seen some people doing something like that :

var int = arg || 400;

And since I don't know in which order I needed to place the value, I tried arg || 400 and 400 || arg, but it will always set int to the value at the right, even if arg is undefined.

I know in PHP you can do something like function doSomething(arg = 400) to set a default value and in a jQuery plugin you can use .extend() to have default property, but is there a short way with a single variable? Or do i have to keep using my way?

Thank for any help and if you can give me resources, it would be appreciated.

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Karl-André Gagnon
  • 33,662
  • 5
  • 50
  • 75
  • 2
    Don't let falsely values bite you in the butt. If you are working with numbers, better off checking for undefined. – epascarello May 22 '13 at 16:18
  • 1
    [**This**](http://stackoverflow.com/a/476445/1823841) might help you to understand the **Coalesce Operator** better. – palaѕн May 22 '13 at 16:20

6 Answers6

15

There's really no shorter clean way than

var int = arg || 400;

In fact, the correct way would be longer, if you want to allow arg to be passed as 0, false or "":

var int = arg===undefined ? 400 : arg;

A slight and frequent improvement is to not declare a new variable but use the original one:

if (arg===undefined) arg=400;
Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • 1
    Note that you shouldn't check for `undefined` in that way, just to be safe. You should use `(typeof arg === 'undefined')` instead. – Colin DeClue May 22 '13 at 16:22
  • 2
    @ColinDeClue Just to be safe against what ? Yourself having redefined `undefined` ? It's not possible in ES5. Passing `null`? – Denys Séguret May 22 '13 at 16:23
  • The first one. `undefined` could be redefined by you or by someone you work with or by a library you import. It shouldn't be, but `undefined` is mutable, so... – Colin DeClue May 22 '13 at 16:25
  • 1
    Well, no, you can't redefine `undefined`. Try it. And even if you could, it makes no sense in trying to protect from stupid libraries, don't use those stupid libraries (supposing there is one). – Denys Séguret May 22 '13 at 16:26
  • Yes, you can, in IE 8, at least. – Colin DeClue May 22 '13 at 16:47
  • 1
    That's why I precised ES5. But do you really saw a library so stupid ? A stupid library could break your code in so many ways, there're no sense in guarding against that. – Denys Séguret May 22 '13 at 16:49
  • Can we code `var arg = arg===undefined ? 400 : arg;` instead of `if (arg===undefined) arg=400;`? – Justin John May 22 '13 at 16:50
  • 1
    @JustinJohn: Yes, you can, but why would you do it? It's more complicated and does the same thing. – Bergi May 22 '13 at 16:53
  • @Bergi Slight and frequent improvement is to not declare a new variable. If we redeclare same variable, what is additional overhead causes? The memory allocation will be same isn't it? – Justin John May 22 '13 at 16:58
  • Just a little clarification, it is possible to change the value of the argument sent to the function? – Karl-André Gagnon May 22 '13 at 17:39
  • @Karl-AndréGagnon Yes, but it changes only the value inside the function (apart if it's an object and you change one of its properties). – Denys Séguret May 22 '13 at 18:11
0
function func(x,y){
   if(typeof(x)==='undefined') x = 10;
   if(typeof(y)==='undefined') y = 20;

   //code goes here
}
Haben
  • 95
  • 5
0

The problem with your solutions is that a value that evaluates to false (for example "false" or "0") also trigger the default value. So for every parameter that could possibly ever have a value that evaluates to false you have to check for "undefined" explicitly.

var int = (typeof x === 'undefined') ? default : x

If this is not possible you can use

var int = x ? x : default
OR
var int = x || default

Another option would be to use the arguments array and check if the parameters were given. But this can only be used if your optional parameters are the last ones.

function test(x, y) {
    var int1 = (arguments.length > 0) ? x : default;
    var int2 = (arguments.length > 1) ? y : default;
}
Werzi2001
  • 2,035
  • 1
  • 18
  • 41
  • or skip the typeof all together and just check if it equals undefined. – epascarello May 22 '13 at 16:22
  • 2
    @epascarello: That's not safe. `undefined` is mutable in some browsers. – Colin DeClue May 22 '13 at 16:24
  • Modern browsers prevent it from being overwritten. Plus in the 12 years I been coding JavaScript I have never had that happen! Now people overriding submit is a different story. And if you are really scared, store a variable that is undefined and use it. – epascarello May 22 '13 at 16:31
  • And chart of support for Immutable undefined: http://kangax.github.io/es5-compat-table/#Immutable%20undefined The fear can die down. – epascarello May 22 '13 at 17:10
  • 1
    @epascarello: Lots of people are still supporting IE8 and IE7. I ran into a user the other day who was still using Windows XP... – Colin DeClue May 22 '13 at 18:53
  • @epascrello: As long as IE7 and IE8 are used (and they are) it is not 100% safe to use "=== undefined". It doesn't matter if "undefined" is usually not redefined (and should not be), it could be and that's the point. – Werzi2001 May 23 '13 at 06:40
0

Not directly related to the question, but why create a new variable to mirror an argument?

In this situation I would use :

!arg && (arg = 400);

However, this tests arg for falsity which means that the values false, 0, '', null and undefined would all cause arg to be set to 400. If this is not the desired result, perhaps a value of 0 is a valid arg value then I usually test argument.length :

function f (arg) {
  !arguments.length && (arg = 400);

This checks if any value was passed and sets arg only in the case that the call specified no arguments at all.

Only is specific instances where 0 is not a desired value would I use the construct

 arg || 400

which again suffers from the falsity test

If it is important that arg be numeric you could use :

 typeof arg !== 'number' && (arg = 400);

which would ensure that arg was a number and in the rest of the code.

In conclusion: it depends on exactly how you want to use the argument, what values are valid and how much you trust the callers of your code.

HBP
  • 15,685
  • 6
  • 28
  • 34
0

I would check arguments.length:

var f = function(arg) {
  var myArg = arguments.length > 0 ? arg : 400;
};
Andreas Louv
  • 46,145
  • 13
  • 104
  • 123
0

In ES6, you can set default value to arguments the same way we do in PHP :

function foo( a = [], b = 'string', c = false ){}

Default value can also be set to a previous argument ou even a function's return value

function foo( a = true, b = a, c = bar() ){}

This will also work with ES6 compilers. The end result will look like this

function foo() {
  var a = arguments.length <= 0 || arguments[0] === undefined ? true : arguments[0];
  var b = arguments.length <= 1 || arguments[1] === undefined ? a : arguments[1];
  var c = arguments.length <= 2 || arguments[2] === undefined ? bar() : arguments[2];
}
Karl-André Gagnon
  • 33,662
  • 5
  • 50
  • 75