Errors
Why does it matter whether we call it LHS or RHS?
Because these two types of look-ups behave differently in the circumstance where the variable has not yet been declared (is not found in any consulted Scope).
Consider:
function foo(a) {
console.log( a + b );
b = a;
}
foo( 2 );
When the RHS look-up occurs for b
the first time, it will not be found. This is said to be an “undeclared” variable, because it is not found in the scope.
If an RHS look-up fails to ever find a variable, anywhere in the nested Scopes, this results in a ReferenceError
being thrown by the Engine. It’s important to note that the error is of the type ReferenceError
.
By contrast, if the Engine is performing an LHS look-up and arrives at the top floor (global Scope) without finding it, and if the program is not running in “Strict Mode” [^note-strictmode], then the global Scope will create a new variable of that name in the global scope, and hand it back to Engine.
“No, there wasn’t one before, but I was helpful and created one for you.”
“Strict Mode” [^note-strictmode], which was added in ES5, has a number of different behaviors from normal/relaxed/lazy mode. One such behavior is that it disallows the automatic/implicit global variable creation. In that case, there would be no global Scope‘d variable to hand back from an LHS look-up, and Engine would throw a ReferenceError
similarly to the RHS case.
Now, if a variable is found for an RHS look-up, but you try to do something with its value that is impossible, such as trying to execute-as-function a non-function value, or reference a property on a null
or undefined
value, then Engine throws a different kind of error, called a TypeError
.
ReferenceError
is Scope resolution-failure related, whereas TypeError
implies that Scope resolution was successful, but that there was an illegal/impossible action attempted against the result.