On null and undefined

An important distinction?
Text saying 'null and undefined in JavaScript and Json', the JS logo, and the website's logo.

I came across a tweet the other day (no link, sorry), where the author said they'd stopped using null in JavaScript, instead using only undefined. The author was encouraging the readers to do the same. From what I can remember, the reason for this was that mixing null and undefined can be confusing and lead to weird bugs in your application.

I've also heard a number of dev friends express negative emotions towards the fact that JavaScript has both null and undefined, saying it makes things harder.

However, I'm in the camp where I think having both null and undefined is a good thing because they are separate concepts. In this post, I want to discuss and put forward the way I view them, both in JavaScript itself, and also as part of a JSON API.

Note: this is largely my own opinion, and I do not have a significant amount of literature to back it up. I welcome opinions and discussions on this!

JavaScript

In JavaScript, both null and undefined represent an absence of value. However, the kind of absence they represent is quite different from one another.

undefined values are values that have simply not been defined. MDN says that 'undefined is a primitive value automatically assigned to variables that have just been declared, or to formal arguments for which there are no actual arguments.':

    let x // x is `undefined`

    var y // y is `undefined`

    const f = (x) =>
      console.log('x is', x)

    f() // prints 'x is undefined'

Additionally, the return value of a function that doesn't return anything is undefined:

    // returns `undefined`
    const g = () => {}

On the other hand, null is never implicitly assigned. It must always be assigned explicitly by the programmer. This makes null well suited for cases when you want to represent a value that can either be present or not, similar to Haskell's Maybe and Rust's Option.

In short

An undefined value is something that hasn't been assigned, while a null value has been assigned that specific value.

Does that matter in your application code? I'm inclined to think that it's not much of a big deal whether you use only one or both. In my experience, most cases will be testing the 'truthiness' of a value anyway, so null and undefined can intermingle freely.

Where it does matter, though, is in areas where these two concepts carry different meanings, such as when communicating via JSON, which is what we'll be looking at in the next section.

Personally, I'm 'Team Both'. I'll use undefined for optional parameters to React components or optional keys of object arguments that I expect, and I'll set a value to null if I intend it to carry a semantic meaning.

What do I think you should do? Whatever fits your use case. If you have no need to differentiate between these two, then it really doesn't matter much what you do. If you'd prefer to only use the one, that's perfectly fine by me.

JSON and APIs

While null and undefined may carry largely the same meaning in JavaScript, they have quite distinct meanings in JSON1 and when communicating with an API. This is especially true when making PATCH requests.

The RFC for the JSON Merge Patch document format (7396) states that when patching, an undefined value should be left as is and a null value should be removed. This means that the two values have wildly different meanings and that mixing them up can cause some very unwanted side effects.

The API story

However, even if JSON works as described above and JavaScript has both undefined and null, a lot of server-side languages don't have this distinction. And they're also often statically typed languages that need to populate a model. This can lead to problems.

Where I work, most of the backend systems are written in C#, where we must have defined classes for JSON payloads. C# doesn't have undefined, so depending on how you configure your system, it can either mark non-existing fields as null or throw an error because it didn't get all the data it needed. When you're working with PATCH as described above, neither of those are ideal.

I don't know of any libraries (in any statically typed languages) that have an elegant solution for this, but I'd be very interested in hearing about it if you do. It may not be applicable to any languages I work with, but just seeing a solution would be very interesting.


So those are my thoughts. I think there is a clear difference between null and undefined, and I support having both. In some cases, they might be interchangeable, but if nothing else, I maintain that they express intent differently, so I think it's worth it just for that.

Footnotes

To be clear: JSON doesn't have an explicit undefined value, but you can leave out a field, which serves the same purpose:

    // JS object
    {
      a: null,
      b: undefined,
      c: 1
    }

    // JSON object, converted
    {
      "a": null,
      "c": 1
    }


Thomas Heartman is a developer, writer, speaker, and one of those odd people who enjoy lifting heavy things and putting them back down again. Preferably with others. Doing his best to gain and share as much knowledge as possible.