You might have heard how null
and undefined
are, practically, the same thing in JavaScript. Today, you will learn how they are completely different syntax-, semantics-, and runtime-wise.
Syntax
This one is the easiest one to explain. Look:
1// This is null:2null34// This is undefined:5undefined
The two use completely different syntax constructs and that is because they represent two different things.
Semantics
Everything in a programming language exists for a reason. There aren't two things that are identical. If you think they are, perhaps you are not considering the use cases that led to their conception and design.
The two in question today are no exception. It helps to think of null
and undefined
semantic value as follows:
undefined
is an implicit absence of value;null
is an expiclit absence of value.
The best way to explain this is to give an example. I will shamelessly steal the one written by Ryan Florence:
Are my keys on the counter?
undefined
: I don't know, I didn't look.null
: I checked, there are no keys.
In more programmatic terms, undefined
points to a space in memory that has been assigned but doesn't yet have any value. null
, on the other hand, points to the allocated pointer in memory that represents invalid memory access.
Stephen Curtis has written a fantastic article on the topic. I highly recommend you read it.
In more practical terms, undefined
is used to describe the absence of value because we don't know if it exists, while null
describes the absence of value because we know it's not there. The user
is undefined
until we fetch them, and the user
becomes null
if the server returned no user.
Runtime
And, of course, the two behave quite differently on runtime.
undefined
is a literal type. That's why you check typeof thing === 'undefined'
to know if the type of thing
is not defined at all.
null
is an object. If you find that wierd, the next sentence will rock your world upside down.
Everything in JavaScript is an object.
Strings are objects, numbers are objects, arrays are objects, classes are objects, and objects are, well, objects. Everything that points to a value is an object. The types of some pointers are narrowed down for convenience, such as typeof 'foo'
is a string, not an object. Since you've just learned that null
is a pointer, consider what type it may be.
This is also the reason why
null
andundefined
don't match using the strict equality operator===
(which includes their types into comparison) but do match when using a loose equality operator==
(which disregards the type and focuses on the value, which is missing for both of them).
On runtime, the difference between an implicit and explicit lack of value can help you handle different scenarios. Though, it's often the value we are after, not the reason why it's missing, which likely leads to the misconceptions such as the one about null
and undefined
being the same thing.
The runtime behavior also confirms the semantic difference here.
1const user = { name: undefined }23// Referencing the existing key that4// equals to undefined...5user.name // undefined67// ...yields the same value and type8// as referencing a non-existing key.9user.address // undefined
Object keys that equal to undefined
are considered missing. Keys that are equal to null
remain present. See for yourself:
1JSON.stringify({ a: undefined, b: null })2// {"b":null}
Hope this settles this question for you. Feel free to share this article with the folk who still mistake null
and undefined
to be the same.