Variable hoisting is how JavaScript handles your variable declarations before it runs your code. It's like JavaScript takes a quick look at your entire program and moves all variable declarations to the top of their scope. Understanding hoisting helps you avoid surprising errors and write clearer code.
Variable Hoisting
Variable Hoisting
In JavaScript, hoisting is a behavior where variable and function declarations are processed before any code is executed. Think of it as the JavaScript engine scanning your code and finding all variable definitions first. It then makes those variables available before the actual line where you wrote them.
What is Hoisting?
Hoisting is JavaScript's way of moving variable and function declarations to the top of their containing scope during the compilation phase, before the code actually runs.
var Hoisting
Variables declared with var are hoisted and initialized with undefined. You can access them before declaration.
let/const Hoisting
Variables declared with let and const are hoisted but not initialized. They enter a 'Temporal Dead Zone'.
Function Hoisting
Regular function declarations are fully hoisted, meaning you can call them before they appear in your code.
Why it Matters
Understanding hoisting prevents unexpected undefined values or ReferenceError messages, making your code more predictable.
What is Hoisting?
What is Hoisting?
Imagine the JavaScript engine has two main jobs. Its first job is to quickly read through all your code. During this first read, it finds every place you declare a variable or a function. It makes a mental note of these declarations.
This means that even if you write a var variable declaration at the bottom of your code, JavaScript already knows about it from the start. However, only the declaration is hoisted, not the value you give it. The value assignment happens later.
1// This line runs BEFORE 'myNumber' is declared below2console.log(myNumber); // Output: undefined34// Here, 'myNumber' is declared and given a value5var myNumber = 10;67// Now, 'myNumber' has its assigned value8console.log(myNumber); // Output: 10
Undefined vs. ReferenceError
When a var variable is hoisted, its declaration is moved up, but it's given a temporary value of undefined. This is different from a ReferenceError, which happens if you try to use a variable that JavaScript doesn't know about at all (e.g., if you never declared it).
Hoisting with `var`
Hoisting with `var`
The var keyword has the most straightforward hoisting behavior. When JavaScript encounters a var declaration, it effectively moves the declaration part to the very top of its scope. However, the part where you give it a value (the initialization) stays exactly where you wrote it.
This means you can access a var variable before its declaration line. But until the line with its actual assignment runs, its value will be undefined. This can lead to unexpected results if you're not careful.
1function showScore() {2 console.log('Before declaration:', score); // Output: Before declaration: undefined34 var score = 100;56 console.log('After declaration:', score); // Output: After declaration: 1007}89showScore();1011// What happens if we don't assign a value?12console.log(message); // Output: undefined (declaration is hoisted, no assignment)13var message;
console.log(gameName); // ?var gameName = 'Space Invaders';
var gameName; // Declaration is moved to the topconsole.log(gameName); // Now it's known, but value is undefinedgameName = 'Space Invaders'; // Assignment stays in place
`let` and `const` Hoisting: The Temporal Dead Zone
`let` and `const` Hoisting: The Temporal Dead Zone
While var variables are hoisted and initialized to undefined, let and const variables behave differently. They are also hoisted, meaning JavaScript knows about them before their declaration line. However, they are not initialized with a default value.
If you try to access a let or const variable before its declaration line, JavaScript will throw a ReferenceError. This period between the start of the scope and the actual declaration line is called the Temporal Dead Zone (TDZ). The TDZ makes your code safer by preventing you from using variables before they are properly set up.
console.log(animal); // undefinedvar animal = 'cat';
// console.log(fruit); // ❌ ReferenceError: Cannot access 'fruit' before initializationlet fruit = 'apple';
console.log(animal); // undefinedvar animal = 'cat';
// console.log(fruit); // ❌ ReferenceError: Cannot access 'fruit' before initializationlet fruit = 'apple';
Always Declare First
To avoid confusion with hoisting and the Temporal Dead Zone, a good rule is to always declare your variables (let or const) at the very top of the block or function where you intend to use them. This makes your code easy to read and predictable.
Avoiding Hoisting Surprises
Avoiding Hoisting Surprises
Hoisting, especially with var, can sometimes lead to tricky bugs because a variable might be undefined when you expect it to have a value. The best way to deal with hoisting is to write your code in a way that makes it irrelevant.
This means always declaring your variables before you use them. This practice aligns perfectly with how let and const work, making your code more robust and easier for others (and your future self) to understand.
Always use `let` or `const`
Avoid var completely in new code. let and const have clearer rules and help you catch errors early with the Temporal Dead Zone.
1let userName = 'Charlie';2const MAX_ATTEMPTS = 3;
Declare variables at the top
Place all your let and const declarations at the beginning of their scope (e.g., at the top of a function or a block). This makes it clear what variables are available.
1function calculateTotal() {2 let subtotal = 0;3 const TAX_RATE = 0.05;4 // ... rest of the function logic5}
Initialize variables immediately
Whenever possible, give your variables a starting value right when you declare them. This prevents them from being undefined.
1let counter = 0;2let message = 'Hello world!';
Beware of Undeclared Global Variables
If you assign a value to a variable without declaring it first (e.g., myVariable = 10; without let or const), JavaScript might create a global variable in non-strict mode. This is very dangerous because it can affect other parts of your program unexpectedly. Always use let or const!
Hoisting Behavior Summary
Hoisting Behavior Summary
| Keyword | Is Hoisted? | Initialized? | Access Before Declaration? |
|---|---|---|---|
| var | Yes | With `undefined` | Yes (value is `undefined`) |
| let | Yes | No | No (`ReferenceError` - TDZ) |
| const | Yes | No | No (`ReferenceError` - TDZ) |
| function | Yes (fully) | Yes (with function definition) | Yes (can call function) |
Test Your Knowledge
Test Your Knowledge
What will be the output of this code? console.log(color); var color = 'blue';
Which type of variable declaration is affected by the Temporal Dead Zone?
What is the best practice to avoid issues related to hoisting?
Consider this code: greet(); function greet() { console.log('Hello!'); } What will happen?
Quick Reference
Quick Reference
- 1Hoisting — JavaScript's behavior of moving declarations to the top of their scope during compilation.
- 2
varHoisting —vardeclarations are hoisted and initialized toundefined. Assignments stay in place. - 3
let/constHoisting —letandconstdeclarations are hoisted but not initialized. They enter the Temporal Dead Zone (TDZ). - 4Temporal Dead Zone (TDZ) — The period where
let/constvariables exist but cannot be accessed before their declaration, causing aReferenceError. - 5Function Hoisting — Regular
functiondeclarations are fully hoisted (both declaration and definition), allowing calls before definition. - 6Function Expressions — Function expressions (like
const func = function(){}) are not fully hoisted; they followlet/construles. - 7Best Practice — Always declare variables with
letorconstat the top of their scope to avoid hoisting surprises. - 8Avoid
var— In modern JavaScript,letandconstare preferred for their clearer, safer hoisting behavior. - 9
undefinedvs.ReferenceError—undefinedis a value for hoistedvarbefore assignment;ReferenceErroris for accessinglet/constin TDZ or undeclared variables. - 10Code Scan — Think of hoisting as JavaScript doing an initial scan of your code for declarations before executing any lines.
Variable Scope
Deepen your understanding of where variables are accessible, which is closely related to hoisting.
Execution Context
Learn about the environments where JavaScript code runs and how variables are managed within them.
Strict Mode
Discover JavaScript's 'strict mode' and how it helps prevent common errors, including some hoisting pitfalls.
Function Declarations
Explore the different ways to define functions and their unique hoisting characteristics.
You've Mastered Variable Hoisting!
You now understand how JavaScript processes variable and function declarations before execution. You know the differences between var, let, and const hoisting, and how the Temporal Dead Zone helps make your code more predictable. This knowledge is crucial for writing robust and error-free JavaScript programs!
Try it in the Javascript Compiler
Run and experiment with Javascript code right in your browser — no setup needed.