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 null
s 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 null
s 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]