Undefined: You’re Using It Wrong

Dima Parzhitsky
4 min readAug 15, 2018

--

One of the very first questions about JavaScript that arises in the heads of beginner developers is “What’s the difference between null and undefined?” This lack of understanding takes place because both of them indicate some kind of emptiness, but each in its own different way.

What are those?

null

The difference is about certainty. null basically says “there’s nothing here, move along.” And this is for real, you can be certain about that. null can be found in places where the value is optional or might not exist. E.g. when finding a word in an input string, it might or might not actually be found:

const input = "Tony Stark";input.match(/Stark/g);
// [ "Stark" ]
input.match(/Iron Man/g);
// null

The second expression returns null because the input string does not include "Iron Man" as part of self.

When dealing with JSON, it has no concept of “undefined”, therefore empty values in JSONs will too be indicated as null:

{
"organization": "S.H.I.E.L.D.",
"head": "Nick Fury, director",
"members": null
}

In fact,JSON.stringify will even omit properties with undefined value:

const value = { redSkull: undefined };JSON.stringify(value);
// "{}"

undefined

undefined is slightly more difficult to understand. In most cases, it says that value of the accessed entity is “hazy” and/or has not yet been well defined. JavaScript tells that “nothing is certain about this value.” For example, if one tried to access a non-existent property of an object:

const person = { name: "Natasha Romanoff" };person.age;
// undefined

… one will predictably get undefined as a response, because… well, the value of this property is not defined, it does not exist. Same thing for uninitialized variables:

let theOtherGuy;theOtherGuy;
// undefined

For undeclared variables though, the situation is somewhat more complicated. When accessing undeclared variables in strict mode, you’ll get a ReferenceError thrown, and this will prevent further execution of logic. In “sloppy” mode however you’ll get an undefined, as if like everything is just fine. That’s why I highly encourage you to always hack in strict mode, because it eliminates a lot of possible errors and misunderstandings right away.

Keep in mind, that neither null, nor undefined has any properties. Accessing them is a ReferenceError still.

How can I use it wrong?

Remember what I’ve said earlier about certainty? Now, what if I used undefined explicitly?

const person = { name: "Natasha Romanoff", age: undefined };// …
// (a lot of code)
// …
person.age;
// undefined

When accessing person.age, the value is undefined, but what does it mean exactly? What it should mean is that the property age does not exist in the person object. But it actually does exist, therefore something else has to be going on here.

The original intention was to indicate that there’s no information about the person’s age at the moment. But the actual response says that the age is “hazy” and is not yet well defined. This behavior might be interesting from a philosophical or sociological perspective, but in the code this doesn’t make sense and usually means that somebody screwed up.

Another problem is that until you see the code, you never know whether this undefined is explicit or not. That is, whether it was written explicitly by developer as a placeholder for future use, or yielded by the JavaScript interpreter as a result of some invalid expression. Needless to say, those situations require different kinds of treatment.

How can I be sure that I use it properly?

First of all, if you decide to never use undefined explicitly, you will make your life and life of your colleagues much easier. Simply put, if you see undefined where should be some value, you can be sure that there is some sneaky error, hiding in the code, that will sooner or later break the app in an unexpected way (if not already).

Additionally, to protect the team from encountering strange values all over the place, you can use some kind of validation strategy, which will guarantee that the value, you’re dealing with now, is exactly what you’re expecting it to be:

function getName(person) {
if (person == null)
throw new Error("The argument has to be defined");
return person.name;
}
getName({ hero: "Hulk", name: "Bruce Banner" });
// "Bruce Banner"
getName();
// Error: The argument has to be defined

Valuer is a best fit for this kind of task. It is a flexible tool, that will allow you to create concise yet informative descriptions for expected values, spot errors early and provide a lot of useful details along the way. Plus, it integrates seamlessly into the existing code:

const { valuer } = require("@valuer/main");const person = { name: "Thor Odinson" };valuer(person.age, "age").as("defined", "number");
// Error: Validation failed: age is undefined
person.age = 1500; // hotfixconst age = valuer(person.age, "age").as("defined", "number");
// (no errors)
console.log(age);
// 1500

Neat, isn’t it?

This little article is my first of a kind. Did it help you to better understand the concepts of null and undefined? If you’re sure that there’s more in that, please, share the thought in the comments section below.

Lucky hacking!

--

--