JavaScript - - By James Edwards

Test for Empty Values in Javascript

The second article in our series covering short, but sweet, functions discusses the problem of testing for empty values. The function in question is called empty(). Similar to the PHP function of the same name, it takes a variable or property and tells you if the value is empty. The definition of empty depends on the value in question.

PHP’s empty() function is annoyingly loose. For example, 0 and false will both return true, which surprises many an unwary developer! Our JavaScript function is far more precise about what kinds of data can be considered empty:

  • undefined or null
  • a zero-length string
  • an array with no members
  • an object with no enumerable properties

Booleans and numbers are never empty, irrespective of their value. Here’s the empty() function’s code:

function empty(data)
{
  if(typeof(data) == 'number' || typeof(data) == 'boolean')
  { 
    return false; 
  }
  if(typeof(data) == 'undefined' || data === null)
  {
    return true; 
  }
  if(typeof(data.length) != 'undefined')
  {
    return data.length == 0;
  }
  var count = 0;
  for(var i in data)
  {
    if(data.hasOwnProperty(i))
    {
      count ++;
    }
  }
  return count == 0;
}

How The Function Works

You can see there are four conditions used to test different data types. The first of these deals with Booleans and numbers, and always returns false. It could be argued that this condition is unnecessary, because, well, just don’t pass Booleans and numbers! But providing this flexibility means you can pass in arbitrary data. The second condition tests the value against undefined and null. This can be particularly helpful for setting defaults for optional function arguments, as shown in the following example.

function doSomething(foo, bar)
{
  if(empty(bar))
  {
    bar = 'default value';
  }
}

Although null is obviously not the same as undefined, for many intents and purposes they amount to the same thing (i.e. this piece of data does not have a wanted value). For example, if you query a web storage object using object syntax, a value that isn’t defined will be undefined, yet the getItem() method will return null.

The third condition in empty() handles anything with a length property. This will detect empty strings and arrays with no members. I did consider an extra condition that checks for strings which are empty or only whitespace. This test is shown below.

if(typeof(data.length) != 'undefined')
{
  if(/^[\s]*$/.test(data.toString()))
  {
    return true;
  }
  return data.length == 0;
}

I decided not to include the previous check because it introduces an ambiguity. Whether or not a whitespace only string can be considered empty is a matter of opinion or application specific. Instead, I opted to keep the function as clear as possible (we’re not writing PHP after all).

The final condition handles objects, iterating through them and counting their enumerable members. If that count is zero, then the object is deemed empty.

Ignoring the Irrelevant

By virtue of being at the end, the final condition handles anything else that makes it through, including functions, regular expressions, elements, and documents. Functions and regular expressions will be treated as empty, because they generally have no enumerable properties. Elements and documents won’t be empty, because they have many properties.

This is an ambiguity that might be worth preventing, but at some point you must ask yourself, “is it really worth it?” Think about the kinds of data you’re likely to test. It will generally be simple variables, arrays, dictionaries, function arguments, form values, Ajax responses, attributes, and text-nodes; it’s unlikely to be a function, regular expression, or DOM subtree. The empty() function walks a fine line between precise evaluation and not wasting time testing every imaginable possibility.

Sponsors