For more tips like this, sign up to the weekly newsletter!

How to check for undefined

To check if a variable is undefined is so commonplace I hardly write any programs without it. I didn't think much about it, but when I started researching this topic, I was surprised by the number of approaches to achieve this simple goal, and that most of them are broken in subtle ways.

Fortunately, most ways are broken only if you deliberately try to break them. So don't rush and refactor everything just yet, but let it be a cautionary tale how messed up a seemingly simple everyday problem can be.

The good way

To check for undefined that works every time, compare with void 0:

let variable;
console.log(variable === void 0); // true

If you look into some libraries, they use this approach. For example, Underscore's isUndefined().

This approach is guaranteed to work. It can not be overridden, can not be shadowed, and does not produce any false positives. It is even three characters shorter than undefined.

The downside? It does not contain the word undefined. It is not immediately obvious what this code does for someone who is not familiar with this approach.

The other ways

Check for falsy values

Check if the value is falsy:

if (variable) {...}

In everyday programming, it is usually a superior way, as it catches nulls and other problematic values. But for checking only for undefined, it falls short. Falsy values also include 0, "", and NaN, so it gives false positives for them.

Variable == undefined
let variable;
console.log(variable == undefined); // true

It filters out 0, "", and NaN, but still returns true for null.

let variable = null;
console.log(variable == undefined); // true
Variable === undefined

A stricter way is to use the strict equality check:

let variable;
console.log(variable === undefined); // true

It correctly filters out nulls but is still prone to another problem. The undefined is defined not as a keyword, but as a property of the global object. While you can not overwrite it in modern browsers, you can shadow it.

let undefined = "a";
let variable;
console.log(variable === undefined); // false
typeof variable == "undefined"

This is a surprisingly lax yet correct way to check for undefined:

let variable;
console.log(typeof variable == "undefined"); // true

It works in every situation, and can not be tampered with.

The downside is it is too forgiving. There is a magic string, and also there is no error if the variable is not declared. As a consequence, if you mistype either of them it just silently misbehaves, which is the worst kind of error.

Declare a new variable

Declare a variable, but do not initialize it:

let realUndefined;
let variable;
console.log(variable === realUndefined); // true

This is what Lodash does. Declare a variable, but never assign a value to it. This leaves it as undefined, and you can use it for comparisons later.

The downside is that you need a new variable.

Use a non-supplied argument as undefined

Declare a function, and use a non-supplied argument:

((undefined) => {
  let variable;
  console.log(variable === undefined); // true
})()

This fixes the case when undefined is shadowed.

The problem is when the caller passes more arguments than you expect:

const iteratee = (variable, undefined) => {
  return variable === undefined;
};

// Map passes (element, index, array)
[2, undefined].map(iteratee) // [false, false]
Try it
References