When programming in JavaScript, you’ll commonly encounter reference errors. There are a number of reasons why you might get one, but fortunately, resolving such an error isn’t too difficult. It’s helpful to know what this error is and why it’s being thrown by the compiler because you’ll save yourself precious debugging time.
In this guide to JavaScript reference errors, you’ll learn how to identify and solve them as well as how to avoid this type of error in the future.
What is a Reference Error In JavaScript, when you create or declare a variable, what you are doing is simply creating a reference to an object with an associated value. Here’s an example:
The previous code tells the JavaScript compiler that whenever it sees the variable a, it should interpret it as its value—meaning, it should see a as the string with the value of Apple. When JavaScript encounters a variable that doesn’t have a declaration, though, it doesn’t know what to do, so it throws a reference error.
In essence, a reference error occurs when JavaScript tries to access a variable that doesn’t exist, hasn’t been defined, or doesn’t exist in the current scope from which you are trying to access it.
Why You Need to Understand Reference Errors It’s important that you understand why JavaScript might throw such an error, especially for the following reasons:
If you understand what’s going on and why, the error is easier and quicker to fix. It is possible to catch this type of error at build time if your code is properly structured. If you spend less time trying to understand why the error occurred, you can spend more time on programming, which improves your workflow. Types of Reference Errors There are a number of different types of reference errors, which can be triggered in different ways. The MDN JavaScript documentation specifies six different types of reference errors that can be triggered within your code, but this guide will focus on the four most important types.
Undeclared or Undefined Variable When a variable reference cannot be found or is not declared, it causes a reference error. New developers are most likely to commit reference errors by forgetting to define variables before referencing them. Here’s an example:
console.log(a)
// ReferenceError a is not defined.
Similarly, declared variables that have been commented out may also cause reference errors when used, like this example:
// const a = "apple"
console.log(a)
// ReferenceError a is not defined.
The solution to this reference error is to ensure that your variables are always declared before using them, as in the following example:
let a = 'apple'
console.log(a)
// apple
Wrong Scope In order for a variable to be available during execution, it must be present in the scope of that execution context—meaning, the variable has to be in the same scope or in a parent scope to be accessible by JavaScript. For example, variables defined inside a function are only accessible inside the function and cannot be accessed outside of it, as shown subsequently:
function inScope() {
let a = "apple";
}
console.log(a);
// ReferenceError a is not defined.
To avoid this type of reference error, make sure that the scope from which you’re trying to access a variable is the scope in which the variable exists:
function inScope() {
let a = "apple";
console.log(a);
}
inScope()
// apple
Additionally, note that the let and const keywords are both block level scoped, while the var keyword is instead globally scoped when used outside a function and function scoped when used inside a function. This can cause certain reference errors when these keywords are used incorrectly.
Strict Mode (Silent Errors) When you assign a value to a variable, JavaScript requires that the variable be declared using var, let, or const. If you use JavaScript in its default mode (without strict mode), declaring a variable without these keywords will result in a silent error—meaning, JavaScript will ignore it even though it is an error. Here’s an example:
a = 'apple'
console.log(a)
// apple,
In strict mode, though, JavaScript will catch this error and throw a reference error:
"use strict";
a = "apple";
console.log(a);
// ReferenceError: a is not defined
To avoid silent errors, always use JavaScript in strict mode so as not to miss similar errors that are typically ignored in JavaScript’s default (or sloppy) mode.
Accessing of a Variable Before its Declaration Another way of triggering a reference error is by trying to access a variable declared with let or const before its actual declaration. This will throw a reference error because the variable hasn’t yet been initialized or read by JavaScript, as shown in the following code:
console.log(a);
let a = "apple";
// ReferenceError: Cannot access 'a' before initialization
As you may have guessed, the solution is to ensure that a variable is always declared first before using so that JavaScript has access to it:
let a = "apple";
console.log(a);
// apple
How to Fix Reference Errors You have several options for addressing reference errors, including the following:
Code editors and IDEs with syntax highlighting might be able to display such issues. Certain tools, such as ESLint , can detect specific patterns and enforce them. TypeScript can identify reference errors when the code compiles and provide recommendations on how to fix them.Static analysis can catch this type of error in your continuous improvement (CI) pipeline before your code is released to production.How to Prevent Reference Errors There are several best practices to follow to keep reference errors out of your projects:
Use extensions that aid with IntelliSense or code completion , such as auto-suggestions, code hinting, and query hints. Use strict mode in JavaScript so that you won’t miss silent errors in sloppy mode. Avoid using the var keyword when declaring variables and, instead, use let or const. Make sure that variables are always declared before calling them. How Meticulous can Help Errors and bugs can still sneak through even the most diligently written code. To prevent disruption to your application, you need tools and techniques to identify and prevent these errors before they hit production.
One tool is Meticulous , a tool for software engineers to catch visual regressions in web applications without writing or maintaining UI tests .
Inject the Meticulous snippet onto production or staging and dev environments. This snippet records user sessions by collecting clickstream and network data. When you post a pull request, Meticulous selects a subset of recorded sessions which are relevant and simulates these against the frontend of your application. Meticulous takes screenshots at key points and detects any visual differences. It posts those diffs in a comment for you to inspect in a few seconds. Meticulous automatically updates the baseline images after you merge your PR. This eliminates the setup and maintenance burden of UI testing.
Meticulous isolates the frontend code by mocking out all network calls, using the previously recorded network responses. This means Meticulous never causes side effects and you don’t need a staging environment.
Learn more here .
Conclusion Reference errors can slow down your JavaScript workflow, especially if you’re not aware of what those errors are or how to solve them. Fortunately, there are simple solutions to these errors, but the best strategy is to be aware of what triggers them so that you can avoid making these errors in your code.
Since mistakes still happen sometimes, you can take additional precautionary measures by choosing a code editor or IDE with intelligent highlighting and support, implementing ESLint to enforce specific patterns, using TypeScript for type checking, or using an automated error handling tool, like Meticulous . The more proactive you are about handling errors, the more you can optimize your team’s productivity.