🍎🍊🍌

Why am I even asking this question, you might think. Well, the thing is that I have been asked this recently and I feel that I didn’t give a good enough answer.

Even though undefined, null and void 0 have something in common, they cannot be compared directly because they represent different concepts with different functionalities.

Instead of doing a one to one comparison between those, I think it makes more sense to explain what each of them is and by doing this, it will be clear how different they are.

undefined

It is a global property or a primitive value.

So, as you see, when you say “undefined” you could potentially be referring to two very different things.

The global property named undefined has a value of undefined by default. This property could be modified up until ES5, when it was made read-only. Therefore if you try to change its value, you won’t be able to:

undefined = 1

console.log(undefined) // undefined

There is a way though to override the value of the global undefined property, even in the latest version of EcmaScript. This can be done by creating a scoped variable called undefined and giving it an arbitrary value. We are basically shadowing the built-in undefined.

(function() {
  var undefined = 1

  console.log(undefined) // 1
})()

When it comes to the value of undefined, this is the default value for any variable that has been declared but not initialised.

var one

console.log(one) // undefined

Also, undefined is the value of an object’s property that does not exist.

var obj = {
  hello: 'world'
}

console.log(obj.goodbye) // undefined

null

It is a primitive value.

Similarly to the undefined primitive value it is also falsy, but it is not an identifier or a global property.

Unlike undefined, it is not being assigned by default to anything in JavaScript. You can only manually set the value of null.

var nothing = null

console.log(nothing) // null

The common use case for null is to assign it to an identifier where an object can be expected but none is relevant.

Because both null and undefined are falsy, when compared using the abstract comparison ==, the result is going to be true. But, using the strict comparison ===, the result is going to be false.

console.log(null == undefined) // true
console.log(null === undefined) // false

void <expression>

It is an operator.

Unlike both undefined and null, it does not represent a primitive value.

The connection between void and the other two is that it always returns the value of undefined.

Its purpose is to evaluate an expression (usually for its side effects) and then return undefined.

console.log(void 0) // undefined
console.log(void (1 + 1)) // undefined
console.log(void (() => 5)) // undefined

One other use for void is to retrieve the original value of undefined when the undefined identifier could have been overridden.

(function() {
  var undefined = 1

  console.log(undefined) // 1

  var realUndefined = void 1

  console.log(realUndefined) // undefined
})()

But, as you remember the global property undefined is read-only, so we can retrieve its value without using void, like so:

(function() {
  var undefined = 1

  console.log(undefined) // 1

  console.log(global.undefined) // undefined
})()

Conclusion

Quick recap:

undefined is a global property or a primitive value

null is a primitive value

void <expression> is an operator

As we have seen, we can find uses for all of them but only one of them is really indispensable: undefined.

We can easily get by without null and especially void which seems to be an artifact of the past.