DEV Community

Cover image for The Difference Between Null and Undefined in JavaScript
Zahra Khan
Zahra Khan

Posted on • Updated on • Originally published at blog.zahrakhadijha.com

The Difference Between Null and Undefined in JavaScript

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?
Giphy

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.

Discussion (34)

Collapse
lukeshiru profile image
LUKESHIRU

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 avoid null. My reasoning for this recommendation is that undefined is the default value for "nullish":

let something; // This is undefined!

const otherThing = {
    foo: "hi"
};
otherThing.bar; // This is also undefined

const aFunction = anArgument => {
    // anArgument here is undefined if no value is passed to this function.
}
Enter fullscreen mode Exit fullscreen mode

So when we want to intentionally define something as "nullish" we can just assign undefined to it. In top of that undefined doesn't have a bug on it as null (typeof null 😓) and if it comes from an API, and undefined value is just omited, so the response is shorter. So with null:

{
    "foo": "foo",
    "bar": null
}
Enter fullscreen mode Exit fullscreen mode

Versus with undefined:

{
    "foo": "foo"
}
Enter fullscreen mode Exit fullscreen mode

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 use undefined.

Cheers!

Collapse
apyrkh profile image
Aliaksandr

What about

const bar = { foo: undefined }
bar.foo === undefined 

// and this
const bar = {}
bar.foo === undefined 
Enter fullscreen mode Exit fullscreen mode

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.

Collapse
lukeshiru profile image
LUKESHIRU

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 assign null to everything that you create without a value? Because when you use null you end up using both null and undefined, but when you use just undefined, you only check for one 😊

Thread Thread
llgcode profile image
llgcode

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.

Collapse
analog_heart profile image
BP

Null and undefined are not the same and serve different purposes.

Collapse
lukeshiru profile image
LUKESHIRU

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 😊

Thread Thread
analog_heart profile image
BP

Real world scenarios, they mean entirely different things.

Thread Thread
lukeshiru profile image
LUKESHIRU

Care to illustrate scenarios in which making the distinction between a null and an undefined value provides any value compared to only using undefined? I mean I already provided examples for my point, but for yours I only got your word 😅

Thread Thread
analog_heart profile image
BP • Edited on

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?

Thread Thread
lukeshiru profile image
LUKESHIRU • Edited on

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.

It can also be undefined:

const persons = [
    {
        firstName: "Luke",
        lastName: "Shiru"
    },
    {
        firstName: "Barack",
        middleName: "Hussein",
        lastName: "Obama"
    }
];
Enter fullscreen mode Exit fullscreen mode

And the TS representation would be something like this:

type Person = {
    firstName: string;
    middleName?: string;
    lastName: string;
};
Enter fullscreen mode Exit fullscreen mode

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?

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.

If you filled a form partially, you can just use undefined.

Undefined means no deliberate choice has been applied to it. Null differs, if you’re using it correctly.

Both mean "nullish/empty/missing value", making the distinction between intentionally left empty or not makes no sense.

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.

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.

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.

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 without undefined you just add to my point: If those other languages only have one type of "nullish" values, why do you need two in JS?

If you work in the field, how long have you been at it?

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!

Thread Thread
analog_heart profile image
BP

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.

Thread Thread
lukeshiru profile image
LUKESHIRU • Edited on

Yes, it would be undefined by default. That’s my point.

So we agree? No need for null here :D

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.

Think 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" and undefined 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:

// The `optional` property is ... well ... optional:
type Example = { optional?: Type };

// Which can be read as this:
type Example = { optional: Type | undefined };

// In contrast, using `null` you have to type it like this:
type Example = { optional: Type | null };
Enter fullscreen mode Exit fullscreen mode

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 use null as a value as well.

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? 🤔

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 into nulls to please the API, that doesn't mean we need to use it ourselves in our JS code.

Apply this to an integer. Do you fallback to zero as default? You’re being too narrow in your reading.

Going back to TS:

type Example = { anInteger?: number };
Enter fullscreen mode Exit fullscreen mode

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 it number | boolean and let it as a false value, so many ways that don't require null.

I’m aware of him, and he is not infallible. This is an example.

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".

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.

Still no relevant. I could have 1 year of experience and already understand why null might not be useful, or have 20+ and think null 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 without null 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 needs null or that "distinction" with undefined (like many languages with 1 or non "nullish" values have proven).

Cheers!

Collapse
zahrakhadijha profile image
Zahra Khan Author

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 over null but I love your explanation!

Thank you!

Collapse
peerreynders profile image
peerreynders • Edited on

One caveat about undefined:

const obj = {
  nil: null,
  nothing: undefined,
};

console.log(obj.nil == undefined);          // true  (non-strict equality)
console.log(obj.nothing === undefined);     // true
console.log(obj.zilch === undefined);       // true

console.log(obj.hasOwnProperty('nil'));     // true
console.log(obj.hasOwnProperty('nothing')); // true
console.log(obj.hasOwnProperty('zilch'));   // false

const array = [null, ,undefined];

console.log(array[0] == undefined);         // true  (non-strict equality)
console.log(array[1] === undefined);        // true
console.log(array[2] === undefined);        // true
console.log(array[3] === undefined);        // true

console.log(array.hasOwnProperty(0));       // true  (value `null`)
console.log(array.hasOwnProperty(1));       // false (hole, empty)
console.log(array.hasOwnProperty(2));       // true  (value `undefined`)
console.log(array.hasOwnProperty(3));       // false (out of bounds)
Enter fullscreen mode Exit fullscreen mode

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:

> console.log([0,,2]);
    (3) [0, empty, 2]
Enter fullscreen mode Exit fullscreen mode

Firefox:

> console.log([0,,2]);
    Array(3) [ 0, <1 empty slot>, 2 ]
Enter fullscreen mode Exit fullscreen mode

ECMAScript 6: holes in Arrays


The void operator returns undefined.

let count = 0;
const result = void(count += 1);
console.log(count);  // 1
console.log(result);  // undefined
Enter fullscreen mode Exit fullscreen mode
Thread Thread
lukeshiru profile image
LUKESHIRU

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:

const array = new Array(1); // Logs as [empty]
array[0] === undefined; // true
array.map(console.log); // nothing logs 🤦🏻
Enter fullscreen mode Exit fullscreen mode

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 than null for the reasons I listed. Before ES6, the global undefined 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.

Collapse
michaelcurrin profile image
Michael Currin • Edited on

Note that var and let keywords let you make undefined but const does not

let x

// syntax error
const y
Enter fullscreen mode Exit fullscreen mode

For bonus points, add a fallback for undefined or null or falsy (zero, empty string)

let x

const y = x || "default"
console.log(y.toUpperCase())
Enter fullscreen mode Exit fullscreen mode

Or in newer versions of JS, you can use this to handle null and undefined, but it won't replace zero or empty string.

let y

const x = y ?? "default"
Enter fullscreen mode Exit fullscreen mode

michaelcurrin.github.io/dev-cheats...

TypeScript can enforce missing values for you so you don't have to throw errors or use a fallback.

Collapse
zahrakhadijha profile image
Zahra Khan Author

I didn't even consider const. Thank you for pointing that out!

Collapse
eljayadobe profile image
Eljay-Adobe

Another fun difference:

var v = void 0 // ... which is undefined
var u = undefined
var n = null
console.log(v === u) //> true
console.log(+u) //> NaN
console.log(+n) //> 0
Enter fullscreen mode Exit fullscreen mode
Collapse
veadro profile image
Veadro

The more I learn about JavaScript's rich diversity of freedom the more I want to just stick with typescript.

Collapse
zahrakhadijha profile image
Zahra Khan Author

Yeah I can't wait to learn Typescript properly!

Collapse
michaelcurrin profile image
Michael Currin

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.

const MY_VAR = process.env.MY_VAR

if (typeof MY_VAR === 'undefined') {
  throw new Error('Must set MY_VAR on environment variables')
}
Enter fullscreen mode Exit fullscreen mode
function foo(abc) {
 if (typeof abc === 'undefined') {
   throw new Error('abc is a required argument')
  }
  console.log(abc)
}

foo(123)
foo(null)
foo() // error
Enter fullscreen mode Exit fullscreen mode

Another use is to skip positional arguments by passing a value explicitly as undefined, assuming it is optional.

foobar("abc", undefined, 456)
Enter fullscreen mode Exit fullscreen mode

In Python this is not need as you can switch to keyword params.

foobar("abc", third_param=456)
Enter fullscreen mode Exit fullscreen mode
Collapse
akuma8 profile image
Attoumane

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.

Collapse
lukeshiru profile image
LUKESHIRU

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 only undefined for everything, or null.

Collapse
blindfish3 profile image
Ben Calder

Generally is seen as a bad practice to use both

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 assigned
  • null: explicitly set to empty

In 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.

Thread Thread
lukeshiru profile image
LUKESHIRU • Edited on

The fact that you can get linting rules to avoid null should be evidence enough, but you can google "avoid null 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 and undefined 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), and undefined is enough for that.

Thread Thread
blindfish3 profile image
Ben Calder

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 😅

Thread Thread
lukeshiru profile image
LUKESHIRU

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 with null 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 😅

Collapse
kwartburge profile image
Kwartburge

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

Collapse
alibahaari profile image
Ali Bahaari

Thanks Zahra Jan!

Collapse
andrewbaisden profile image
Andrew Baisden

Great explanation this is something that many people keep asking questions about.

Collapse
richardaddicott profile image
Richard Addicott

Your analogy about the boxes to reinforce the explanation is brilliant.
Great article!

Collapse
zahrakhadijha profile image
Zahra Khan Author

Thank you! 😊 Appreciate you reading it!

Collapse
alphakappa44 profile image
LeSmallPrincipito

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 😃.

Collapse
zahrakhadijha profile image
Zahra Khan Author

WHOOPS lol yes! I fixed it!