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 JSON[1] 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
}
- [1]
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 }