88

I was wondering, can you create a function with an optional parameter.

Example:

function parameterTest(test)
{
   if exists(test)
   {
     alert('the parameter exists...');
   }
   else
   {
     alert('The parameter doesn\'t exist...');
   }
}

So if you call parameterTest() then the result would be a message "The parameter doesn't exist...". And if you call parameterTest(true) then it would return "the parameter exists...".

Is this possible?

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
Guido Visser
  • 2,209
  • 5
  • 28
  • 41
  • 1
    http://www.openjs.com/articles/optional_function_arguments.php – Jared Oct 22 '12 at 20:53
  • It is a very old question, but apparently viewed daily, thanks for the input. I edited the original post to make it more clear. – Guido Visser Nov 09 '16 at 11:08
  • I think the real-world situation is how to check arguments of a function. `controller`, `service`, `model` layer. There will be a lot of arguments need to be checked. – Lin Du Feb 15 '19 at 04:33

9 Answers9

119

This is a very frequent pattern.

You can test it using

function parameterTest(bool) {
  if (bool !== undefined) {

You can then call your function with one of those forms :

 parameterTest();
 parameterTest(someValue);

Be careful not to make the frequent error of testing

if (!bool) {

Because you wouldn't be able to differentiate an unprovided value from false, 0 or "".

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • @Johan pretty sure you can use it as a function and an operator. seems to work in chrome at least – sachleen Oct 22 '12 at 21:01
  • 1
    Looks like youre right :) https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/typeof – Johan Oct 22 '12 at 21:03
  • -1 for suggesting useless overhead and also screwing it up internally. Just call `if( bool ) { }` or `return !!bool` – jAndy Oct 22 '12 at 21:08
  • @dystroy: if one needs to specifically check `0`, it should just go into the condition `if( bool || bool === 0 )` – jAndy Oct 22 '12 at 21:21
  • Its more unlikely than likely, that you *want* to allow values like empty strings or zero, so just checking for presence and truthyness is far more reasonable (IMO). In other case is specific and should get checked by `typeof bool === 'number'` respectively `typeof bool === 'string'` anyway. – jAndy Oct 22 '12 at 21:28
  • 4
    -1 for suggesting === undefined - try var undefined = true before your code and see what happens ... correct check would be typeof book === 'undefined' – griffin Oct 09 '14 at 12:25
  • you're comparing a variable to some other variable - that doesn't even answer the question. I don't care which name you use, but effectively you're teaching people wrong stuff. It might work most of the time, but it could also get you into code hell, and really, there's no reason NOT to use the correct approach. Also wrt. performance: http://jsperf.com/typeof-vs-variable <- there's no difference on my machine using chrome. – griffin Oct 10 '14 at 09:32
  • 10
    @griffin if someone writes `var undefined` in their code, they deserve to suffer. `window.undefined` is unwritable for the same reason `window.infinity` and `window.NaN` are - they are supposed to be used to represent their respective values defined by the specification. – John Dvorak Oct 10 '14 at 09:40
  • 21
    @griffin You're absolutely right. We should stop using `undefined`, it could change at any moment! Might as well stop using `Object` and `Date`, someone might have tampered with those, and you should never ever trust `document.createElement`, it could be overridden! – Zirak Oct 10 '14 at 09:41
  • this still doesn't distinguish an explicit `undefined` from an unsupplied argument, though. Consider checking `arguments.length` instead. – John Dvorak Oct 10 '14 at 09:42
  • You're both only partially right - undefined is only reserved from javascript 1.8.5 upwards, so for example all IE versions which don't support that will allow a var called undefined. Also `window.undefined` is not the same as `var undefined`! The first one is a window property, the second one is a local variable! And Object at least has been reserved keyword for nearly forever, and Date probably for nearly as long (would have to look at the javascript specification for that) Edit: @JanDvorak is absolutely right of course and his suggestion is even more correct. – griffin Oct 10 '14 at 09:44
  • 2
    @griffin Absolutely, `undefined` is a local variable. That's why [it's a property of the global object](http://es5.github.io/#x15.1.1.3), and obviously [`Object` can't be overwritten](http://jsh.zirak.me/185i9) – Zirak Oct 10 '14 at 09:46
  • 2
    `Object` is not a reserved keyword and never was. It's a defined property in the global scope, that happens to coincide with the constructor `{}` has. And `window.undefined` can be overriden in two ways: 1) by your own code - then you deserve it, or 2) by the page you script against - but IE8 doesn't support userscripts and firefox and chrome both use ES5. – John Dvorak Oct 10 '14 at 09:47
  • 1
    To me it's the same point as teaching people about '===' vs '==' - while the later one may work most of the time, it's just not the same, and many times does not reflect the intent of the author as well as possibly leading to bugs. – griffin Oct 10 '14 at 09:47
  • 2
    @griffin if you're keen on supporting netscape then by all means worry about undefined not being a reserved word .... – Patsy Issa Oct 10 '14 at 09:47
  • 1
    @griffin This discussion is getting too lengthy for comments - if you'd like to continue, we'd love to discuss this with you [in chat](http://chat.stackoverflow.com/rooms/17/javascript-whatever-plus-a-very-serious-duck). – Zirak Oct 10 '14 at 09:48
  • 1
    @griffin I'm pretty sure `=== undefined` reflects the author's intent quite well and is more readable than `typeof`. – John Dvorak Oct 10 '14 at 09:48
  • @JanDvorak Thanks for the useful links, seems I was wrong about `Object`. And yeah, I'll join the chat for that ;) @PatsyIssa IE8 does not support ES5 either, and unfortunately at my company we still have to support IE8 – griffin Oct 10 '14 at 09:52
  • 4
    @griffin in short: `undefined` has the exact same status as `Object`: It's an unwritable (since ES5) property of the global object, defined by the specification, and if you shadow it it's your fault. There's no reason to use one but not the other. Moreover, if the page you're userscripting against does redefine one or the other, greasemonkey _still_ protects you against that by providing a separate global scope for each userscript. – John Dvorak Oct 10 '14 at 09:52
  • 2
    Upvoted again ; For anyone reading these comments: we had a chat about the topic and it seems that `undefined` was already there in IE8 (JScript 1.5 based on ES3), which means this way of checking is actually fine. Still, if you want to check for argument count, you should use arguments.length to prevent bugs leaking due to something being passed as undefined (two differend use cases). – griffin Oct 10 '14 at 10:26
14
function parameterTest(bool)
{
   if(typeof bool !== 'undefined')
   {
     alert('the parameter exists...');
   }
   else
   {
     alert('The parameter doesn\'t exist...');
   }
}
Johan
  • 35,120
  • 54
  • 178
  • 293
7

In JavaScript, if you neglect to give a parameter it will default to undefined.

You could try it out for yourself easily enough, either in your browser console or using JSFiddle.

You can check for the existance of the parameter, as you say, and that way write a function that can use a parameter or not. However, JavaScript Garden (a great resource) recommends staying away from typeof in most other cases, as its output is just about useless (check out the table of results of typeof).

Johanna Larsson
  • 10,531
  • 6
  • 39
  • 50
  • 1
    As an alternative, jquery does provide a `$.type` method that works consistently across browsers. – Kevin B Oct 22 '12 at 21:04
  • 2
    That link says typeof is ONLY useful for this situation, which makes it good enough for this question. – EralpB Feb 24 '14 at 16:21
6

init default values if not exists:

function loadDialog(fn, f, local, anim) {
  switch (arguments.length) {  
    case 1: f=null;
    case 2: local=false;
    case 3: anim=false;
  }
  ...
}
  • Pls do consider of explaining your code and how it would help, so that others can be benefited from this. – Amit Verma Jul 12 '20 at 09:23
  • 2
    This what the right answer for me because I needed to distinguish between a value not being passed at all vs passing undefined to the function. The other answers don't account for passing undefined. – Kevin Beal Jul 14 '21 at 15:03
  • Cryptic but nice. Also allows to tell apart `loadDialog(fn, undefined)` from `loadDialog(fn)`. – Walter Tross Jun 20 '23 at 11:50
3
function parameterTest(p) {
    if ( p === undefined)
        alert('The parameter doesn\'t exist...');
    else
        alert('the parameter exists...');
}
manman
  • 4,743
  • 3
  • 30
  • 42
3

best way to check: if the param is not undefined

function parameterTest(param) {
    if (param !== undefined)
    ...

the param could be also a variable or a function name

ungalcrys
  • 5,242
  • 2
  • 39
  • 23
3

None of these answers were doing it for me. I needed to know if someone had used the parameter or not. If someone invoked the function passing undefined I wanted to treat that as them using that value as the parameter. Anyway, the solution was quite easy using some modern JS:

function parameterTest(...test) {
  if (test.length) {
    return `exists`;
  } else {
    return `not exists`;
  }
}

parameterTest(123);         // exists
parameterTest(undefined);   // exists
parameterTest();            // not exists
parameterTest(window.blah); // exists

For older browsers you can use arguments:

function parameterTest() {
  if (arguments.length) {
    return "exists";
  } else {
    return "not exists";
  }
}
Jamie Twells
  • 1,924
  • 4
  • 26
  • 56
  • 1
    The same answer was already added. You explained the problem better though. – Kevin Beal Jul 14 '21 at 15:17
  • 1
    Thank you! Twenty answers of ignoring `undefined` and then this. +1 for a general solution, and for *not* encouraging the ancient art of the `arguments` pseudo-array. – Silvio Mayolo Jan 29 '22 at 18:02
0

null == undefined is true

if (arg == null){
    // arg was not passed.
}

Code example:

var button = document.querySelector("button");

function myFunction(arg){
  if(arg == null){
    alert("argument was not passed.");
  } else {
    alert("argument " + arg + " was passed.");
  }
}
<button onclick="myFunction('foo');">click to fire function w arg</button>
<br><br>
<button onclick="myFunction();">click to fire function w/o arg</button>
Ronnie Royston
  • 16,778
  • 6
  • 77
  • 91
-2

I know this is old, but this is my preferred way to check, and assign default values to functions:

function testParamFunction(param1, param2) {
    param1 = typeof param1 === 'undefined' ? null : param1;
    param2 = typeof param2 === 'undefined' ? 'default' : param2;

    // exit if the required parameter is not passed
    if (param1 === null) {
        console.error('Required parameter was not passed');
        return;
    }

    // param2 is not mandatory and is assigned a default value so 
    // things continue as long as param1 has a value
}