Type Error Vs Reference Error in JavaScript
Here are two errors that I see in my browser console all the time when working with JavaScript.
There are tons of different JavaScript errors and they can be found in the Mozilla docs, here.
For this post, I wanted to specifically get into the difference between TypeError
vs ReferenceError
.
A simple example of both can be see here:
Let's see what is really going on...
ReferenceError
When you create a variable, all you are doing is creating a reference with a value.
var a = "I'm a string"
tells the JS compiler that any time it sees the variable a
, it is seeing a string with a value of "I'm a string"
.
Without that variable declaration, JS has no idea what to do when it comes across a
because there is no reference, so it throws an error.
var a = "I'm a string";
console.log(a) // I'm a string
console.log(b) // Uncaught ReferenceError: b is not defined.
In the above example, JS knows what to do when it comes across a
. It hasn't the slightest idea what to do when it comes across b
so it throws a tissy fit and a ReferenceError
.
TypeError
A TypeError
is not too far off from a ReferenceError
. The JS compiler is telling you that however you are attempting to use your variable is not how it is intended.
Here is one example:
var a = "I am a string";
console.log(a) // I am a string
console.log(a()) // Uncaught TypeError: a is not a function
The error message is clean and telling you exactly what is wrong in this very simple example. You are trying to invoke a
as though it is a function, but yet, it is a lowly string.
What you are looking for is:
var a = function(){
return "I am a string"
}
console.log(a()) // I am a string
Cannot read property of undefined
This is a common TypeError
I see so I wanted to address it because it is very preventable. I will often see it when missing a null check on async fetches. I might call an API and be expecting something like response.data.someProperty.anotherProperty
and before I check to make sure that response
, response.data
, and response.data.someProperty
are truthy, I try accessing response.data.someProperty.anotherProperty
.
Here is an incorrect example:
function async doSomethingAsync(url){
let response = await goFetchSomeData(url);
let dataToLogToConsole = response.data.someProperty.anotherProperty;
console.log(dataToLogToConsole);
}
// Uncaught TypeError: cannot read property 'someProperty' of `undefined`.
In the above example, we are trying to access someProperty
from the response.data
property, but that seems to be of type undefined
.
What we should be doing is checking that all of the parent properties exist and are truthy before we try to access their nested properties.
The example above would throw a TypeError
because you are trying to access data from a property that is of type undefined
. The JS compiler sees you as trying to do the same thing as trying to invoke a string in the previous example, your code is not using the type of response.data
or a
as intended.
Here is a more correct example:
function async doSomethingAsync(url){
let response = await goFetchSomeData(url);
if(response && response.data && response.data.someProperty){
let dataToLogToConsole = response.data.someProperty.anotherProperty;
console.log(dataToLogToConsole);
}else{
console.error('The data was not available');
}
}
This example will either log the nested data, or will log the error to the console. It will not throw a type error.
Tldr;
JS Errors are intimidating when you see them in the console with their alerting red letters. Often I freak out a bit and my heart rate rises, no matter how often I see these errors.
When actually looking at what the error is telling you and then debugging my code, the JS errors are there to help and not scare you, though they can definitely be frustrating at times.
In short, a ReferenceError
is just saying that the variable you are using has no reference. A TypeError
is telling you that you are not using the variable's type correctly. It's incredibly simple if you think about it.
Top comments (0)