Dealing with null
and undefined
is always fun in JavaScript. It really is, once you've got the knack of it. Until then, it's a nightmare. Understanding the difference between null
and undefined
seems to be the initiation rite of the JavaScript tribe. So be it. Let me be your priest guiding you through your initiation!
In a nutshell
How many times have you seen this in a JavaScript code or even a JavaScript tutorial?
if (person === null || person === undefined) { ... }Or this?
if (typeof person === 'object') { ... }Or even this?
if (person == null) { ... }With a few notable exceptions, you can forget about all that. It's OK to use the shortcut:
if (!person) { ... }Adding insult to injury, the second option I showed is even broken. It doesn't detect null
values because JavaScript considers null
an object.
What's it all about?
In most programming languages, null
is the default value of variables you didn't care about. As the name indicates, null
and zero are closely related. On the hardware level, null
and zero are the same thing.
undefined
is a peculiarity of the JavaScript language. It's necessary because JavaScript is a slot machine. Not a one-armed bandit, of course, but a different kind of slot machine.
JavaScript allows you to modify objects at runtime. Almost every other programming language considers classes immutable. JavaScript does not. It doesn't even know classes. It implements object-oriented programming with mutable objects. More to the point, the structure of objects is mutable. You can create an object and add attributes or methods later. You can think of a JavaScript object as a collection of empty slots. When a method is defined, it's put into the empty slot. Likewise, when you first assign a value to an attribute, the new attribute is put into an empty slot. After that, the attribute has a defined value. It may be null
. That's still a difference to the situation before populating the slot.
For some reason, JavaScript allows you to read attribute and methods before putting them into a slot. That's why undefined
came into being. It's the state of attributes and methods that haven't been defined yet.
A class-oriented language like Java doesn't have to make this distinction. Java classes are structurally immutable. Every attribute and method is defined from day one (or from the first nanosecond, to be pedantic). Java gets away without inventing undefined
.
The semantics behind undefined and null
There you have it. undefined
means you haven't thought about the value of the attribute. null
, in contrast, means you did put some thought to it. You've deliberately assigned it null
to indicate it doesn't have a value. It's not a value yet to be assigned. It's a value that has been left blank for a reason.
Reality check
That's the theory. In real life, hardly anybody cares about the difference. What counts is the difference between proper values and invalid values. The latter being both undefined
and null
. It doesn't matter. You can't do much with either. Few people make a difference between undefined
and null
.
The JavaScript language reflects this, offering a useful shortcut:
if (!person.firstName) { throw new Error("Please enter the first name of the person."); }It doesn't matter if the first name is null
or undefined
. In both cases, the code raises an exception. You don't have to write something like if (person.firstName === undefined || person.firstName === null) { ... }
. The simple negation does the trick just as well. In this particular case, it also covers the empty string, which is a bit surprising. On the plus side, that's almost always what you need.
When you're using the shortcut, keep the JavaScript truth matrix in mind. There are a few surprises, but less than urban rumors claim, as Craig Gidney reports. For convenience, I add Craig's version of the JavaScript truth table:
Wild type casts
What to think of this code?
if (person.firstName == null) { throw new Error("Please enter the first name of the person."); }It looks innocent enough, but it's a bummer. Note the double equals sign. It forces a type conversion. In the eyes of the double equals sign, undefined
and null
are identical. But an empty string is something different.
This may come in handy every once in a while, but in general, I prefer the explicit triple-equals comparison for such a scenario. It means you have to check both undefined
and null
, but at least there are no surprises. And, like mentioned above, the simple !
operator usually does the trick just as well.
Wrapping it up
JavaScript rookies usually have a hard time learning the difference between null
and undefined
. I certainly had. It becomes a lot clearer when you learn that JavaScript objects are slot machines. They offer empty slots, which attributes and methods may populate at runtime. Until then, they are just undefined
. After populating such a slot, you still need a default value. In this case, it's null
, not undefined
. Only it's not - before defining an attribute, it is undefined. After defining it you can still assign it to undefined
. That's where the semantics I've described above is broken. But don't worry. In everyday life, that's not a big problem. Just use the shortcuts !
and !!
(aka "Bang, bang, you're a boolean!"), and you're good to go.
Dealing with undefined values is fun because it's so much shorter, so much more concise than in other languages!