What is a ReferenceError?
As defined by ECMAScript 5, a ReferenceError
indicates 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 ReferenceError
occurs when the scripting engine is instructed to get the value of a reference that it cannot resolve the base value for:
A Reference is a resolved name binding. A Reference consists of three
components, the base value, the referenced name and the Boolean valued
strict reference flag. The base value is either undefined, an Object,
a Boolean, a String, a Number, or an environment record (10.2.1). A
base value of undefined indicates that the reference could not be
resolved to a binding. The referenced name is a String.
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 ReferenceError
occurs.
Consider what happens when you type foo
in the console when no such variable exists: you get a ReferenceError
because the base value is not resolvable. However, if you do var foo; foo.bar
then you get a TypeError
instead of a ReferenceError
— a subtle perhaps but very significant difference. This is because the base value was successfully resolved; however, it was of type undefined
, and undefined
does not have a property bar
.
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 foo
is resolvable, do
if(this.foo) //...
In the global context, this
equals the window
object so doing if (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.