views:

453

answers:

11

I know of two methods of setting a default parameter, but I would like to know what the preferred method is.

function Foo(par1, par2)
{
    if(par2 == null)
        par2 = "my default"
}

or

function Foo(par1, par2)
{
    par2 = par2 || "my default"
}

or is there a better way than either of these?

EDIT:

I would also like to know how others handle multiple optional parameters such as this: We have several functions like this in internal libraries (I think they're pretty ugly).

function Foo(par1, par2, par3)
{
    if(par2 == null)
        par2 = "my default"
    if(par3 == null)
        par3 = "my default"
    // Do something
}

And to call it:

Foo("Parameter one",null,true)
+3  A: 

I usually use the second one because it adds less signal.

mat
A: 

Never heard of the second way you mentioned, that is interesting. I would do:

function Foo(par1, par2)
{
    par2 = par2 ? par2 : 'default value';
}

But now that you bring to my attention your second method, I think I would use that just because it is less typing.

Logan Serman
Guess number <0> or value <empty string> and many other would be treated wrongly.
Sergey Ilinsky
doesnt work for par2=false and default value = true. use undefined as below
Simon_Weaver
+1  A: 

If you use jquery, you can do:

function foo(params){
 var params = $.extend({}, {bar: '2'}, params);
 alert(params.bar);
}
foo(); //Alerts 2
Pim Jager
+5  A: 

first one is actually wrong, since they would be undefined, not null.

par2 !== null would return true for this case.

since javascript, if loosely compared, compare null, undefined, false to the same value, I would suggest checking explicitly for an undefined value.

if (par2 !== undefined)
        par2 = "my default";

or

    par2 = par2 !== undefined ? par2 : "my default";

This will allow you to pass on values like false or null.

However, your second approach is convenient, but only in the case you know that you would never pass false or null.

jishi
Good point! At least someone did it right.
Gumbo
Asker is using ==, not ===. So first example is actually not wrong.
Crescent Fresh
It would work, but it's wrong in the sense that he doesn't know what he is actually matching.
jishi
+1  A: 

Similar and related questions have been asked before.

Christoph
+4  A: 
Sergey Ilinsky
Nice if your function indeed accepts, null, undefined, 0, '' as params
Pim Jager
Pim, the question was in general, there were no details on the values, right?
Sergey Ilinsky
It wasn't criticism. I was just saying that this is something which you don't really need if your function doesn't want those values as arguments. (Also I upvoted your answer because it really is a good answer for those cases.)
Pim Jager
+1  A: 

The choice I make depends on the parameter type and the default value required.

For example, this will assign the 'default value' if par2 is false, 0, an empty string, null or undefined:

par2 = par2 || 'default value';

That behavior may not be what is expected or required.

Grant Wagner
+1  A: 

Personally I think the second form is just outright cleaner and more readable, certainly moreso than sergey's arguments inspection - though that can have it's place - but I prefer to pass extensible objects for args than have to maintain arg signatures.

e.g.

function Foo(myArgs)
{
    myArgs.par1 = myArgs.par1 || "my default"
    myArgs.par2 = myArgs.par2 || "my default"
}
annakata
And what about if your argument represents a falsy value?
Pablo Cabrera
Good question. I'd use a ternary similar to jishi's where it mattered - but mostly I find falsys *are* the default values, or are questionable values to pass at all. Bit unsure why I got the accepted on this one tbh, as I was really extending other correct answers with the object arg technique :)
annakata
No need to define a myArgs variable. There already is an internal arguments variable: See section 10.1.8 in http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
some
@some - I'm well aware of that, but creating your own class gives you centralised reusable control over the data, giving you cheap validation, defaults, something approaching type-safety if you wish, and improves readability. By comparison the arguments var is really a rather obfuscated and clunky.
annakata
oh and further to that - arguments[n] is hardly the same as myArgs.foo
annakata
Although this isn't too much different from several other methods, It does seem to be the closest match for what I need to do.
chills42
A: 

The one thing you have to think about when using the solution of

var foo = bar || 123;

is what values of bar that evaluate to false. It could cause you problems down the road.

Eric

epascarello
A: 

If you're passing many arguments to a function you could do something like:

function myFunc() {
    arguments[0] = arguments[0] || "default value for first argument";
    arguments[3] = arguments[3] || "default value for fourth argument";
    alert(arguments[3]);
}
Luca Matteis
+1  A: 

What about this one:

function myFunc(arg1, arg2, arg3) {
    switch (arguments.length) {
        case 0 : arg1 = "default1";
        case 1 : arg2 = "default2";
        case 2 : arg3 = "default3";
    }
}
Pablo Cabrera