Back to JavaScript
2026-04-135 min read

Variable hoisting

Learn Variable hoisting step by step with clear examples and exercises.

Title: Mastering Variable Hoisting in JavaScript

Why This Matters

Variable hoisting is an essential concept in JavaScript that helps you write cleaner, more predictable code. Understanding variable hoisting is crucial for debugging real-world issues, acing interviews, and writing efficient programs. In this lesson, we'll explore what variable hoisting is, its implications, and how to avoid common pitfalls.

Prerequisites

Before diving into variable hoisting, you should have a basic understanding of the following concepts:

  • Variables in JavaScript
  • JavaScript execution context
  • Block scope and function scope
  • Basic control structures (if-else, for, while)

Core Concept

In JavaScript, variables are declared using either var, let, or const. However, only the var keyword follows a special rule called hoisting. Hoisting is the process where variable declarations are moved to the top of their respective scope (either global or function) during the compilation phase, before any code execution.

Hoisting allows you to use a variable before it's declared with the var keyword without throwing an error. This behavior can be both helpful and confusing, depending on how you use it in your code.

For example:

console.log(x); // undefined
console.log(y); // ReferenceError: y is not defined

var x = 10;
let y = 20;

In this code snippet, we are logging the values of x and y before they're declared with their respective keywords. Even though y has not been declared yet, JavaScript moves only the declaration to the top of the scope, so it appears as if we have access to the variable:

var x; // implicitly moved to the top of the global scope
let y; // implicitly moved to the top of its respective block (function or code block)

console.log(x); // undefined
console.log(y); // undefined

x = 10;
y = 20;

However, it's essential to note that hoisting only applies to declarations, not assignments. This means that if you try to access a variable before declaring it with var, JavaScript will throw an error:

console.log(z); // ReferenceError: z is not defined

Hoisting and Scope

Variable hoisting also affects the scope of your variables. Variables declared with var are function-scoped, meaning they're accessible within the entire function in which they're declared, as well as any nested blocks (code blocks enclosed by curly braces). On the other hand, variables declared with let and const are block-scoped, meaning they're only accessible within their respective blocks.

function example() {
console.log(x); // undefined (var is function-scoped)
let y = 20;
var x = 10;
console.log(y); // 20
}
example();
console.log(x); // 10 (var is accessible outside its function)
console.log(y); // ReferenceError: y is not defined (let and const are block-scoped)

Worked Example

Let's take a look at an example that demonstrates variable hoisting in action:

function foo() {
console.log(a); // undefined
console.log(b); // ReferenceError: b is not defined
var a = 10;
let b = 20;
}
foo();
console.log(a); // 10 (hoisting moves the declaration of `var` to the top of the function)
console.log(b); // ReferenceError: b is not defined (let and const are not hoisted)

In this example, we have a function called foo(). Inside the function, we are trying to log the value of b before it's declared with the let keyword. This results in a ReferenceError, as JavaScript does not hoist assignments for let and const.

However, outside the function, we can access the variable a even though it's declared inside the function. This is because hoisting moves only the declarations to the top of the scope, not the assignments. After calling the foo() function, we can see that the value of a has been correctly assigned and can be accessed outside the function.

Common Mistakes

Hoisting Variables with let and const

Unlike var, variables declared with let and const do not follow hoisting behavior. This means that you cannot access a variable before it's declared with these keywords, or assign a value to a variable multiple times within the same scope:

console.log(x); // ReferenceError: x is not defined (let and const are not hoisted)
let x;
x = 10;
x = 20; // TypeError: Assignment to constant variable.

Confusing Hoisting with Initialization

Variable hoisting only moves declarations, not assignments. This means that if you try to access a variable before it's been assigned a value (even though the declaration has been moved), JavaScript will return undefined. It is essential to understand this distinction to avoid confusion and bugs in your code:

console.log(x); // undefined
console.log(y); // ReferenceError: y is not defined

let x;
const y = 10;
x = 20;

Practice Questions

  1. Write a function that logs the sum of two variables declared with let, but only if both variables have been assigned values before calling the function.
function sum(a, b) {
if (typeof a !== 'undefined' && typeof b !== 'undefined') {
return a + b;
} else {
console.log('Both variables must be defined and assigned values.');
return null;
}
}
console.log(sum(10, 20)); // 30
console.log(sum(undefined, 20)); // Both variables must be defined and assigned values.
  1. Given the following code snippet, what will be logged to the console? Why?
function foo() {
bar(); // undefined
var bar = function() { console.log('Hello'); };
}
foo();

In this example, we are calling a function bar() before it's declared within the foo() function. Since JavaScript hoists declarations but not assignments, the call to bar() results in an error (ReferenceError: bar is not defined) when the foo() function is called.

FAQ

Q: Can I use hoisting with let and const variables?

A: No, only variables declared with the var keyword follow hoisting behavior in JavaScript. Variables declared with let and const do not get hoisted.

Q: What happens if I declare a variable twice within the same scope using var?

A: In JavaScript, declaring a variable multiple times within the same scope using var results in the last declaration taking precedence over any previous declarations. This can lead to unexpected behavior and should be avoided.

console.log(x); // undefined (first declaration)
var x;
var x = 10;
console.log(x); // 10 (last declaration takes precedence)
Variable hoisting | JavaScript | XQA Learn