Scope is like a lookup list for variables. It enforces a set of rules related to the accessibility of these variables for the currently executing code.
During compilation, variables are allocated memory. During execution, the variable assignments are performed.
For example, consider the statement: var a = 2;
In compilation
Memory is allocated for a
.
In execution
The Engine looks for a
in the current scope. If it is present there, it assigns the value 2
to it. If not, it searches for the variable in nested scopes. If the variable is not found in any nested scope, a ReferenceError is thrown.
If a variable is not found in the current scope, the Engine continues searching in the outer containing scopes. This process continues until the global scope is reached.
ReferenceError
If a reference to a variable is not found (if its Right-Hand Side (RHS) lookup fails) in the currently executing scope or the nested scopes, a ReferenceError
is thrown.
Declaring a variable without var
causes the Engine to search through all nested scopes. If it fails to find the variable, it creates a new variable in the global scope. However, in strict mode, a ReferenceError
is thrown.
TypeError
If a variable reference is found (RHS lookup is successful), but an operation on its value is impossible (such as invoking it as a function, or trying to reference a property on an undefined or null value), then a TypeError
is thrown.
ReferenceError vs TypeError
- ReferenceError is scope-related. It occurs when scope resolution fails.
- TypeError occurs when scope resolution is successful, but an illegal operation is attempted on the resolved value.