How to Fix Cannot access lexical declaration before init in JavaScript
In this tutorial, you'll learn about How to Fix Cannot access lexical declaration before init in JavaScript. We cover key concepts, practical examples, and best practices.
The Problem
JavaScript throws "Cannot access lexical declaration 'X' before initialization" when code in a block scope tries to reference a let or const variable before it is initialized, due to the temporal dead zone.
Quick Fix
Step 1: Move the reference after the declaration
Referencing a let variable before its line throws:
function example() {
return x;
let x = 10;
}
console.log(example());
ReferenceError: Cannot access 'x' before initialization
Declare before using:
function example() {
let x = 10;
return x;
}
console.log(example());
10
Step 2: Check for closures capturing block-scoped variables
A closure capturing a let variable from an outer scope before initialization:
function test() {
console.log(getX());
let x = 10;
function getX() { return x; }
}
test();
ReferenceError: Cannot access 'x' before initialization
Use var or restructure so the closure is created after initialization:
function test() {
let x = 10;
function getX() { return x; }
console.log(getX());
}
test();
10
Step 3: Reorder class declarations
Classes are block-scoped and not hoisted like functions:
const obj = new MyClass();
class MyClass {}
ReferenceError: Cannot access 'MyClass' before initialization
Define the class before instantiating:
class MyClass {}
const obj = new MyClass();
console.log(obj instanceof MyClass);
true
Step 4: Avoid accessing let in the same scope before its line
This is the most common pattern, usually from reordered code:
const total = price + tax;
let price = 100;
let tax = 20;
ReferenceError: Cannot access 'price' before initialization
Move declarations to the top:
let price = 100;
let tax = 20;
const total = price + tax;
console.log(total);
120
Prevention
- Declare all variables at the top of their scope before any logic.
- Use
constfor values that do not change and keep declarations visible. - Configure ESLint
no-use-before-defineto error on TDZ violations. - Restructure code to avoid closures referencing uninitialized variables.
Common Mistakes with let hoisting
- Misunderstanding that
Stringis[Char]with poor performance for large text operations - Using
foldlinstead offoldl'causing stack overflow on large lists - Forgetting
deriving (Show, Eq)on custom data types needed for debugging
These mistakes appear frequently in real-world JS code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro