Reference error is a scope resolution failure error. In a TypeError, scope resolution is successful, but we try to perform
an illegal action on the variable that is not permitted.
The following example will give a clear idea about these two types of errors.
function foo(a){
console.log(a+b);//ReferenceError b is not defined
b=a;
}
foo(2);
Executing the above function results in a TypeError because, b is not defined at the point when the compiler reaches the console.log(a+b) statement,
Notice the b is not declared with a var keyword.
Now consider the function below,
function foo(a){
console.log(a+b);
var b=a;
}
foo(2);//NaN
When the above function is executed, the compiler hoists the variable b, in the function scope, the function looks something like this after compilation
function foo(a){
var b;//--> b has a value of undefined at this point
console.log(a+b);
b=a;
}
foo(2);//NaN
when the engine executes the console.log(a+b), at this point a has a value of 2 and b has a value of undefined hence its logs NaN.
As the expression below evaluates to NaN
2 + undefined;// evaluates to NaN
Now coming to TypeError, Consider the following block of code, as usual we will take the function foo.
function foo(a){
console.log(a+b.toString()); //TypeError Cannot read property 'toString' of undefined
var b = a;
}
foo(2);
Going with the above logic, the compiler turns the function into something like the code below, after the variable b gets hoisted
function foo(a){
var b ;// b has a value of undefined at this point
console.log(a+b.toString()); //TypeError is thrown
b= a;
}
foo(2);
Within the scope of the function, variable b gets hoisted, and hence has a value of undefined before the line console.log(a+b.toString()). In this line we try to convert b which is undefined at this point to string, doing so, we try to do an illegal operation, hence TypeError is thrown. Scope lookup was successful for variable b, but we performed an illegal operation. Hence TypeError was thrown.