Undefined Arguments in JavaScript

Sometimes it’s the most basic things that make me wonder. In this case, I was trying to figure out the best way to determine that an argument had not been passed to a function. That is, we have a function that expects function(one, two), but someone might invoke it with function(one). And we’d like to know that fact within the function, perhaps to set some default values.

(I feel that I should have this stuff under my belt, but I often have to remind myself of the weird rules of JavaScript. I should probably be studying the writings of Doug Crockford more.)

EDIT: Since writing this post, I realized that undefined is not a keyword, but rather a variable name, which is usually not defined by programmers–but it could be. So if you are testing whether an argument has been defined, you should probably use the typeof operator.  However, there is another alternative: void(0).  This always returns as undefined, so one can compare against that.  So you could write something like this:

if(myVariable === void(0){
    //do amazing things
}

I have changed the code below accordingly.

I read about this in a thread about programming language oddities on Stack Overflow.

So I start to wonder about this sort of thing, and I turn to the awesome JS Bin. I set up a test there, and I can provide you with a link to the test… I love that.

But JS Bin is rather impermanent, and just in case that’s not working out, here is the original test and the results.

code


/* check for an absent argument to a function */

var testIt = function(one, two){
  gnomeSane = '';
  if(two === void(0)){
    gnomeSane += "two is undefined. (two === void(0))<br />";
  }
  if(two === null){
    gnomeSane += "two is null. (two === null)<br />";
  }
  if(two === false){
    gnomeSane += "two is false. (two === false)<br />";
  }
  if(two === ''){
    gnomeSane += "two is an empty string. (two === '')<br />";
  }
  if(two === 0){
    gnomeSane += "two is zero. (two === 0)<br />";
  }

  if(two == void(0)){
    gnomeSane += "two is equivalent to undefined. (two == void(0))<br />";
  }
  if(two == null){
    gnomeSane += "two is equivalent to null. (two == null)<br />";
  }
  if(two == false){
    gnomeSane += "two is equivalent to false. (two == false)<br />";
  }
  if(two == ''){
    gnomeSane += "two is equivalent to an empty string. (two == '')<br />";
  }
  if(two == 0){
    gnomeSane += "two is equivalent to zero. (two == 0)<br />";
  }

  if(typeof two == "undefined"){
    gnomeSane += "type of two is 'undefined'. (typeof two == 'undefined')<br />";
  }

  if(!two){
    gnomeSane += "not two is true. (!two)<br />";
  }

  gnomeSane = gnomeSane == '' ? 'two is '+two : gnomeSane;
  document.write('<p>'+one+'<br />'+gnomeSane+'</p>');
}

testIt('<b>The second argument is not being passed to the function.</b>');
testIt('<b>Now the second argument is null.</b>', null);
testIt('<b>Now the second argument is false.</b>', false);
testIt('<b>Now the second argument is an empty string.</b>', '');
testIt('<b>Now the second argument is zero.</b>', 0);
​

results

The second argument is not being passed to the function.
two is undefined. (two === void(0))
two is equivalent to undefined. (two == void(0))
two is equivalent to null. (two == null)
type of two is 'undefined'. (typeof two == 'undefined')
not two is true. (!two)

Now the second argument is null.
two is null. (two === null)
two is equivalent to undefined. (two == void(0))
two is equivalent to null. (two == null)
not two is true. (!two)

Now the second argument is false.
two is false. (two === false)
two is equivalent to false. (two == false)
two is equivalent to an empty string. (two == '')
two is equivalent to zero. (two == 0)
not two is true. (!two)

Now the second argument is an empty string.
two is an empty string. (two === '')
two is equivalent to false. (two == false)
two is equivalent to an empty string. (two == '')
two is equivalent to zero. (two == 0)
not two is true. (!two)

Now the second argument is zero.
two is zero. (two === 0)
two is equivalent to false. (two == false)
two is equivalent to an empty string. (two == '')
two is equivalent to zero. (two == 0)
not two is true. (!two)

conclusions

If you want to really just test for an undefined argument use:

two === void(0)

or

typeof two == 'undefined'

I prefer the clarity of the latter. But we will need to be careful if we do that, because typeof null is equivalent to ‘object’.

If you want to test for both undefined or null use either:

two == void(0)

or

two == null

Using both might make the code more clear, but it is not strictly necessary.

If you want to test for all “off values” (undefined, null, false, empty string, zero), then use:

!two
This entry was posted in JavaScript, Tests and tagged , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>