During a code review a college suggested that we could change one of my javascript switches on an non-existant value:
Which seemed to make sense because, since we don’t want to perform any type coercion on the null object, this should be faster.
However, when I reloaded the page, the comparison (previously returning true) was now returning false. Confused, I fired up the web inspector to discover this:
Ok, so evidently null and undefined are different things, even though I’d been using them interchangeably (like many web developers, I made the mistake of diving in javascript without bothering to learn it…)
Undefined and null
So what exactly is the difference between the two? Undefined is the default value javascript variables take before they are assigned a value. Null, on the other hand, is the intentional absence of a value. When using ==, the types of both undefined and null coerce to false.
The many meanings of undefined
So, you can just do this:
and in most cases, that will work. However, undefined is actually 3 things in javascript; a type, a value and a variable. The issue with the above code is that we’re not checking if the some_var is ‘undefined’, we’re checking if it’s equal to the global variable called undefined. Undefined (the variable) exists uninitialised in javascript in the global scope and like all uninitialised variables, it is set to undefined (the value). For more detail on this I highly recommend checking out Angus Croll’s post on the subject
The problem is, somewhere in your code or in a library, someone else could overwrite the undefined variable to be a string:
Which would mean all your comparisons to undefined would compare to a string! There’s no good reason to do this, but given the potential for javascript variables leaking into the global scope, it’s worth not comparing to the undefined variable in case someone in a library or other javascript file has accidentally (or maliciously!) overridden it.
It’s worth noting that ECMA 5 forbids setting the value of undefined, but currently, only Safari enforces this.
Comparing the types
So if we can’t compare to the undefined variable, what should we do? Remember I said that undefined was also a type? Well, an uninitialised variable’s value is still of the type undefined. So we can use javascript’s typeof method to get the values type as a string:
Hopefully this clears up not just how to test assignment correctly in JavaScript, but also why we do it this way.