Everything I’ve ever read indicates that in Javascript, the boolean value of an undefined variable is False. I’ve used code like this hundreds of times:
if (!elem) {
...
}
with the intent that if “elem” is undefined, the code in the block will execute. It usually works, but on occasion the browser will throw an error complaining about the undefined reference. This seems so basic, but I can’t find the answer.
Is it that there’s a difference between a variable that has not been defined and one that has been defined but which has a value of undefined? That seems completely unintuitive.
What is a ReferenceError?
As defined by ECMAScript 5, a
ReferenceErrorindicates that an invalid reference has been detected. That doesn’t say much by itself, so let’s dig a little deeper.Leaving aside strict mode, a
ReferenceErroroccurs when the scripting engine is instructed to get the value of a reference that it cannot resolve the base value for:When we are referencing a property, the base value is the object whose property we are referencing. When we are referencing a variable, the base value is unique for each execution context and it’s called an environment record. When we reference something that is neither a property of the base object value nor a variable of the base environment record value, a
ReferenceErroroccurs.Consider what happens when you type
fooin the console when no such variable exists: you get aReferenceErrorbecause the base value is not resolvable. However, if you dovar foo; foo.barthen you get aTypeErrorinstead of aReferenceError— a subtle perhaps but very significant difference. This is because the base value was successfully resolved; however, it was of typeundefined, andundefineddoes not have a propertybar.Guarding against ReferenceError
From the above it follows that to catch a ReferenceError before it occurs you have to make sure that the base value is resolvable. So if you want to check if
foois resolvable, doIn the global context,
thisequals thewindowobject so doingif (window.foo)is equivalent. In other execution contexts it does not make as much sense to use such a check because by definition it’s an execution context your own code has created — so you should be aware of which variables exist and which do not.