Whenever I encounter null
or undefined
, I get incredibly confused by how each data type is used in JavaScript.
I mean, what's the difference? Don't they both express the concept of nothing?
I decided to do some research to gain a deeper understanding of the two data types. It's helpful to have this knowledge so that you can use them correctly when needed. I've also learned that sometimes, the difference between null
and undefined
comes up in interviews. π
Introduction
JavaScript has 7 primitive data types, two of which are null
and undefined
.
Null is an assignment value, which means that you can assign the value null
to any variable when you want that variable to be empty. It is intentionally left blank and will point to an empty value.
let hasCat = null;
// nullish
Undefined is a variable that exists but hasn't been initialized YET. Which means that later, I can come back to my variable and assign it a value that it did not have before. So if I declare a variable without a value, it's just considered non-initialized.
let currentJob;
// undefined
The way that I understood both of them is that, yes, they are both very similar in that they both don't have a value that you're trying to access. If you were to compare the two in JavaScript, implicitly they're the same because JavaScript considers them both as empty values. But since they are both different data types, if you compare them explicitly, they will result in a falsey value.
null == undefined;
// truthy
null === undefined;
// falsey
Analogy
Imagine you're moving. You bought a bunch of boxes. You have to pack up your stuff and put them inside of those boxes. But you're disorganized so you forget to label what's in the boxes. You have 5 boxes that are full of things and you have 2 boxes that are left empty. You want to label your boxes but you've already put tape on them, so you tell yourself you'll come back to it later. For now the 5 boxes are TBD. And the 2 boxes are leftover and empty. In code, that would look like:
let fiveBoxes = undefined;
let twoBoxes = null;
The five boxes with a bunch of stuff in them are considered undefined because they have things in them but you don't know what's in it YET. The two boxes left empty are MEANT to not have anything in them.
Null vs. Undefined
The difference between the two data types is:
Undefined
- Declared
- Uninitialized
- Engine Assigned
Null
- Lack of
- Empty/void
- Non-existent
- User assigned
Go to your console, and type in:
typeof null
typeof undefined
What do you get?
Conclusion
Null and undefined are not the same. It's important to learn the difference between the two so you avoid any buggy behavior in your code and have a clear understanding of why they exist. It's also cool if you're able to clearly state the difference in an interview too π
Feel free to hit me up on Twitter if you're still confused! Or if you'd just like to chat.
Top comments (37)
Nice breakdown! My 2 cents:
A lot of programming languages have "nullish" values, and debate about using them or not, and JS is the only popular one that has 2 π ... the most common recommendation is to only use one, and my personal recommendation is to only use
undefined
and avoidnull
. My reasoning for this recommendation is thatundefined
is the default value for "nullish":So when we want to intentionally define something as "nullish" we can just assign
undefined
to it. In top of thatundefined
doesn't have a bug on it asnull
(typeof null
π) and if it comes from an API, and undefined value is just omited, so the response is shorter. So withnull
:Versus with
undefined
:The only "downside" is that you have to type 5 more characters when you write it explicitly in your code, but compared to all the downsides of using
null
, I still prefer to just useundefined
.Cheers!
What about
This is not the same, right? Also in the latest typescript it was implemented to differentiate these 2 cases.
I prefer
null
for nullish values.It's the same from the practical standpoint. Something undefined or with the value undefined. TS used to support optional properties as properties that can be defined with the value undefined, or not be defined at all. Recently they added an opt-in option to make this more explicit (the details about it can be found here) but the way the vast majority code stuff they don't stumble with the inconsistencies mentioned in there (that's why is opt-in instead of being opt-out).
When you say you prefer
null
, you mean that you assignnull
to everything that you create without a value? Because when you usenull
you end up using bothnull
andundefined
, but when you use justundefined
, you only check for one πI agree 'Because when you use null you end up using both null and undefined, but when you use just undefined, you only check for one' I guess this is the main reason. Undefined is like optional for me and I never use null and undefined with different meaning in my code. I mean I don't have any example of code that treat it differently when having a variable or property with the type undefined or null. Thank to the strict option of typescript, I check every case.
This is incredible feedback and so good to learn!
Yeah I've watched some videos on the topic where it's best practice to use
undefined
overnull
but I love your explanation!Thank you!
One caveat about
undefined
:An
undefined
value is inconclusive with regards to the existence of the property/element within an object/array.Also note that browser developer tools will mark "holes" in arrays with
empty
.Chromium:
Firefox:
ECMAScript 6: holes in Arrays
The void operator returns
undefined
.Yup, Arrays are a special case because when you create a new one, it uses "empty" instead of undefined, because unless you assign an actual value to it, to save memory it doesn't assign anything to it (not even undefined), which is kinda tricky:
Don't get me wrong, I'm not saying
undefined
is perfect by any means, but from my point of view at least, is far better thannull
for the reasons I listed. Before ES6, the globalundefined
was a regular value, so you were able to reassign its value to whatever you want. So yeah, far from perfect, but at least better than his little brother, at least for me.Null and undefined are not the same and serve different purposes.
You're not the first to point that out, and I already answered why in practice (real world scenarios) they are the same, and I'm not the only one that thinks this way. Check the thread π
Real world scenarios, they mean entirely different things.
Care to illustrate scenarios in which making the distinction between a
null
and anundefined
value provides any value compared to only usingundefined
? I mean I already provided examples for my point, but for yours I only got your word πNull is a valid value to represent anything that is nullable in nature. Undefined means it does not exist because itβs unset and was never set.
Does a person have a middle name? If yes, it will have an alpha value. If they do not have a middle name, it would be null. This is to say that the actual value is deliberately meant to be no middle name. This differs from undefined which is to say that the value does not exist because it was unset. Perhaps the form to enter the person details was only partially completed. Undefined means no deliberate choice has been applied to it. Null differs, if youβre using it correctly.
Taking this further, letβs say your data store is Mongo. You started by only collecting first and last name, and have thousands of documents that are missing this field. Later, you decide to include a middle name. Null is still valid, because not everyone has a middle name. You decide that, in order to facilitate data collection, you want to prompt any existing users that are missing this field. You could prompt those that have not yet taken an action because you can clearly see that the field is missing/undefined. They may choose to acknowledge that they have no middle name, at which point youβd save null to the document.
Now you want to integrate with a third party web api. That third party system is written in a strongly typed language (Java or C#). They only have the notion of null. You have forgotten to send over this middle name field because of how jsβs type system works, and because of how the deserializers work, they do not know whether to reject the request or not. After all, they default to null if the field is not present in the json payload. The system has now made an incorrect assumption because of a limitation between being able to discern whether the data should be there but wasnβt or whether it was there and was intended to be null. This problem exists because thereβs only one null.
Undefined is metadata that describes a js value thatβs integral to its duck typing system. Itβs got an entirely different purpose than null.
If you work in the field, how long have you been at it?
It can also be
undefined
:And the TS representation would be something like this:
Why would we spend memory with a
null
value there, or bits with a JSON coming from the back-end, when we can just omit what is not there?If you filled a form partially, you can just use
undefined
.Both mean "nullish/empty/missing value", making the distinction between intentionally left empty or not makes no sense.
If the
middleName
field becomes required, then you could say that if it isn't a string, then it wasn't filled yet (undefined
), and if is intentionally left empty, then is just an empty string""
, again no need fornull
here.You're basically describing a poorly designed API/back-end. If you have a back-end that doesn't have the concept of an optional/undefined property, then you should acomodate for that. Front-end shouldn't be fixing issues of the back-end (which is a pretty common mistake). Besides mentioning languages with only
null
and withoutundefined
you just add to my point: If those other languages only have one type of "nullish" values, why do you need two in JS?I don't know how is my time in this field relevant, but if you really want to know, I been doing this for 10+ years, and again I'm not the only one that says this, if you don't want to take my word for it, maybe you'll take the word of Douglas Crockford (the author of "JavaScript: The Good Parts" and JSON) here. That guy has been in this game for way longer than me, and he doesn't uses
null
, and his reasons are even simpler than mine:undefined
is what JS uses to refer to "nullish" values, so he uses the same.Cheers!
I cannot effectively respond as Iβm in my phone.
If you filled a form partially, you can just use undefined.
Yes, it would be undefined by default. Thatβs my point.
Both mean "nullish/empty/missing value", making the distinction between intentionally left empty or not makes no sense.
They do not because one requires an action to be applied. Intent rather than an assumption. Null does not mean a missing value in the way you are describing. That is expressly the purpose of undefined in js.
You're basically describing a poorly designed API/back-end. If you have a back-end that doesn't have the concept of an optional/undefined property, then you should acomodate for that. Front-end shouldn't be fixing issues of the back-end (which is a pretty common mistake).
First - and my main point - is to point out the flaw in those languages that happens to not exist in js because js actually got something right. But secondly, do you often have control over the third party systems you integrate with? π€
If the middleName field becomes required, then you could say that if it isn't a string, then it wasn't filled yet (undefined), and if is intentionally left empty, then is just an empty string "", again no need for null here.
Apply this to an integer. Do you fallback to zero as default? Youβre being too narrow in your reading.
I'm not the only one that says this, if you don't want to take my word for it, maybe you'll take the word of Douglas Crockford (the author of "JavaScript: The Good Parts" and JSON) here.
Iβm aware of him, and he is not infallible. This is an example.
I don't know how is my time in this field relevant, but if you really want to know, I been doing this for 10+ years
Itβs relevant because you keep citing βreal world examplesβ, yet are advocating for lossy handling of data. It makes no sense and does not fit well with practical experience, imo.
So we agree? No need for
null
here :DThink about it, really really think about it. That "requires an action to be applied" part is particularly interesting for me. Folks like you use
null
as "intentionally left blank" andundefined
as "missing", but if you really really think about it, they are both missing values, either if you do it intentionally or not. I gave you an example in TS because it just makes the types of JS more explicit, but when something is "optional" you type it like this:So you're explicitly saying "this will be of given Type or it will be
null
", you aren't saying anything about it being optional, you're just saying that you'll usenull
as a value as well.One common discussion in typed languages is if we actually need a "nullish" type at all (you can see languages like Elm that doesn't even has a "nullish" type). JavaScript ridiculously enough has 2. The idea of not using
null
is mainly to keep "nullish" values to a minimum, and when you actually need one, use it for optional values (in functional languages is generally called Maybe).If I send an object as the one I show in the previous comment with a missing property, and the backend yells at me because it expects that value there or
null
, that's a bad back-end, but if we don't have communication with the back-end team, we can just use an abstraction layer on top of the API that deals with missing values turning them intonull
s to please the API, that doesn't mean we need to use it ourselves in our JS code.Going back to TS:
If the value is optional, it can be either a number or
undefined
. If you have that scenario of yours in which suddenly that value becomes required, then it depends on your architecture, but you could make it so "intentionally left blank" is a-1
, or you have another property just to track that, or you make itnumber | boolean
and let it as afalse
value, so many ways that don't requirenull
.Nobody is, my point was that there are lots of folks that don't use
null
, if we can trust the downloads of this plugin, almost 60k people in the last week decided to forbid it in their projects. I mean is not "just me".Still no relevant. I could have 1 year of experience and already understand why
null
might not be useful, or have 20+ and thinknull
is here to save us from our sins π€£This discussion was extended long enough, I understand where you're coming from, I hope you understood why for me (and many more folks) only using
undefined
for "nullish" values is enough. Don't get me wrong, if coding withoutnull
gets confusing for you, or you actually need it in order to make certain "distinctions" for some reason, good for you ... but that doesn't mean that everyone needsnull
or that "distinction" withundefined
(like many languages with 1 or non "nullish" values have proven).Cheers!
Here you lost the argument! Because when you say
anInteger? : number | boolean
, you are actually trying to distinguish "missing by default" from "intentionally not set". Now you can express that in many ways:All are equivalent now (well not really, not yours). You're simply choosing to "spell"
null
differently in each case. BTW, moreover, do you realizenumber | boolean
does not make much sense? Do you know why? THINK. Because now you can have:I'm sure you didn't mean that? That is what happens when you do not understand "states" with precision. When you want to have
3 states
(likenumber
,undefined
andnull
(or"nothing"
if you spell it differently), your suggestion introduced a bug and you end up having4 states
.The point with the
number | boolean
was that we don't need it to benumber | null
, we can keep it asnumber?
which means that we can omit it, or we can use any other type that is used for other stuff, likeboolean
, or even uses other properties for that and keep it just asnumber
. So I said that as an example of hownull
is not necessary to express that theoretical "third state" for which you supposedly neednull
, and you took that as a way of saying that I endorse having four states.The main point remains: There's no actual value distinguishing between a "nullish" value and an "intentionally nullish" value. So both are nullish, and both are handled the same way, and reducing the amount of nullish values to 1 or even 0 (with stuff like Haskell's
Maybe
) is way better than having two as JS has.BTW, there's a message at the top of my profile stating that I'm no longer active in DEV. I saw this just because I forgot to disable notifications. I'm currently blogging on my website, and I addressed
null
in an article there. So if you want to keep discussing this, I suggest you ping me through Twitter, but I'm about to disable notifications, so I'll not see further replies.Cheers!
Looks like you didn't read my post carefully. The point is, your point is WRONG.
number | boolean
is NOT the same asnumber | null
. You cannot give a WRONG alternative as a replacement. Also, again, you do NOT understand "states with precision". In many places,X | undefined
could mean the same thing asX | null
if you do not require the precision. But when you need it,X | undefined
is NOT sufficient. You have to INVENT something, which is precisely why you gave the examples of-1
andnumber | boolean
. Both are WRONG. At least,number | "nothing"
makes better sense!See. I told you. You do NOT understand states. Your example has a FOURTH state as well.
You think Haskell has
0
nullish value?Maybe
is exactly how Haskell implements a nullish value, or an absence of value, or a missing value. Just because it's spelled differently and accessed differently, does NOT mean it does not encapsulate the idea of nullish value. It's BETTER designed null.Note that var and let keywords let you make undefined but const does not
For bonus points, add a fallback for undefined or null or falsy (zero, empty string)
Or in newer versions of JS, you can use this to handle null and undefined, but it won't replace zero or empty string.
michaelcurrin.github.io/dev-cheats...
TypeScript can enforce missing values for you so you don't have to throw errors or use a fallback.
I didn't even consider const. Thank you for pointing that out!
Another fun difference:
The more I learn about JavaScript's rich diversity of freedom the more I want to just stick with typescript.
Yeah I can't wait to learn Typescript properly!
Good point in other comment on filling in very common encounters of undefined as when getting a non-existent key from an object an getting undefined (in Ruby you get null and Python you get an error) and an argument that is not defined (Python will give an error when it is not defined but in JS you must validate yourself).
Also noteworthy for how to check for undefined.
Another use is to skip positional arguments by passing a value explicitly as undefined, assuming it is optional.
In Python this is not need as you can switch to keyword params.
I didnβt still understand the difference. As a Java developer I can understand the null meaning but trying to explain the difference with undefined in JSβ¦ I simply canβt.
Simply put:
JavaScript has 2 "nullish" values, which for your Java dev perspective are the same. One is used as the default value by JS for something without a value or missing, which is
undefined
, the other is used to explicitly say that something is "null" (similar to Java). Generally is seen as a bad practice to use both, so we use either onlyundefined
for everything, ornull
.That's the first time I've heard this. Do you have any evidence to back this up?
To my mind the distinction between the two is quite clear:
undefined
: no value has yet been assignednull
: explicitly set to emptyIn practice I agree they're interchangeable, but occasionally it's useful to be able to distinguish between a value that hasn't been set and one that has been explicitly emptied.
The fact that you can get linting rules to avoid
null
should be evidence enough, but you can google "avoidnull
in JS" and you'll get a plethora of articles on the subject. The first time I heard about this was in a talk by Douglas Crockford (the author of "JavaScript: The Good Parts" and JSON), which basically said "One nullish value is enough" (Source).Now playing my "UNO reverse card":
In practice, how many scenarios do you know where you actually need that distinction you mentioned?
I mean I haven't used
null
in years andundefined
was enough all this time, but maybe there is a scenario you have in mind that I haven't ran into all this years. From my point of view, I either have a value, or not (either implicitly or explicit), andundefined
is enough for that.I searched and didn't find much more than 'you can save some inconvenience by avoiding null' π€·
I don't have a very strong opinion on this. I just hadn't seen anything that justified describing the use of null as bad practice. If there was I might have to speak to the backend devs I work with π
Yup, Google will not give you the same results it gives me, but my first result is this article, not to mention that the creator of
null
calls it the "billion-dollar mistake" π€£). You could say is an "inconvenience", but even as such, why would you inconvenience yourself withnull
when you can just avoid it? Even if you don't want to call it a "bad practice", we can agree is not a "good practice" either πThey both point to value that doesn't exist
comparing them even result to true( null == undefined )
but they are lots of difference between them.
while undefined can be intentionally or unintentionally set as value, null in the other hand must be intentionally set as a value
and they're both different in the type they return
Great explanation this is something that many people keep asking questions about.
Your analogy about the boxes to reinforce the explanation is brilliant.
Great article!
Thank you! π Appreciate you reading it!
Thanks Zahra Jan!
I think you have a small bug there:
"undefined === undefined;
// falsey"
Where it should be:
"null === undefined;
// falsey"
Shouldn't it? I liked the explanation though π.
WHOOPS lol yes! I fixed it!