Demystifying JavaScript Hoisting: How var, let & const Behave

Piyush kantPiyush kant
5 min read

1. What is JavaScript Hoisting?

Hoisting refers to JavaScript's default behavior of moving declarations (not initializations) to the top of the scope before code execution. Essentially, when the code runs, variable and function declarations are processed first, which is why you can sometimes use a variable or function before it is declared in the code.

However, only declarations are hoisted, not the initializations.

For example:

console.log(myVar); // undefined
var myVar = 5;

Even though myVar is declared after the console.log, JavaScript hoists the declaration to the top. The code is interpreted as:

var myVar;
console.log(myVar); // undefined
myVar = 5;

In this example, the variable myVar is hoisted but remains undefined until the line where it is initialized.


2. How Does Hoisting Affect var, let, and const?

Hoisting behaves differently for variables declared with var, let, and const. Here's how:

var Hoisting

Variables declared with var are hoisted to the top of their scope (either global or function scope). However, they are initialized with undefined until the line where they are explicitly assigned a value.

Example:

console.log(hoistedVar); // undefined
var hoistedVar = 10;
console.log(hoistedVar); // 10

In this case, the var declaration is hoisted, but the initialization (hoistedVar = 10) is not, so the first console.log returns undefined.

let and const Hoisting

Variables declared with let and const are also hoisted, but they are not initialized. These variables exist in a "temporal dead zone" (TDZ) from the start of the block until the declaration is encountered. Accessing them before their declaration results in a ReferenceError.

Example:

console.log(hoistedLet); // ReferenceError: Cannot access 'hoistedLet' before initialization
let hoistedLet = 20;

The key difference here is that accessing a let or const variable before it’s declared results in an error, rather than undefined.

Comparison Table: var vs let vs const Hoisting

Variable TypeHoistedDefault InitializationTemporal Dead ZoneCan be Redeclared
varYesundefinedNoYes
letYesNoYesNo
constYesNoYesNo

3. Function Hoisting Explained

Functions in JavaScript are hoisted differently depending on whether they are declared as function declarations or function expressions.

Function Declarations

A function declaration is fully hoisted. This means the entire function (including its body) is hoisted to the top of its scope, allowing you to invoke the function before its declaration in the code.

Example:

console.log(add(5, 10)); // 15

function add(a, b) {
  return a + b;
}

The function declaration add is hoisted to the top, so the call to add(5, 10) works even before the function is declared.

Function Expressions

Function expressions, whether assigned to var, let, or const, are only partially hoisted. The variable that holds the function is hoisted, but the function definition itself is not.

Example:

console.log(subtract(10, 5)); // TypeError: subtract is not a function

var subtract = function(a, b) {
  return a - b;
};

In this case, the var subtract declaration is hoisted, but the assignment (function(a, b) { ... }) is not, which results in a TypeError.


4. Common Pitfalls with Hoisting

Accessing Variables Before Declaration (let and const)

As explained earlier, accessing variables declared with let or const before their declaration will throw a ReferenceError due to the temporal dead zone.

Example:

console.log(myConst); // ReferenceError
const myConst = 100;

Variable Overwriting with var

Since var allows redeclarations, it can lead to unexpected results:

var message = "Hello";
var message = "World"; // No error
console.log(message); // "World"

To avoid such issues, prefer using let or const.

Function Hoisting Confusion

Beginners often get confused between function declarations and expressions. For instance:

console.log(greet()); // TypeError: greet is not a function

var greet = function() {
  return "Hello!";
};

Because greet is a function expression, only the var greet is hoisted, not the function body.


5. Best Practices for Avoiding Hoisting Issues

  1. Always Declare Variables at the Top: To avoid confusion and potential errors, always declare your variables and functions at the top of their respective scope.

     let count = 0;
     const max = 100;
    
  2. Use let and const Instead of var: Since let and const provide block-level scoping and prevent redeclarations, they are generally a safer option.

  3. Understand Temporal Dead Zones: Be mindful of the temporal dead zone when using let and const and avoid accessing these variables before their declarations.

  4. Be Aware of Function Expressions: Know when you’re dealing with a function declaration vs. a function expression. If you need the function to be hoisted, use a declaration.


6. Hands-On Coding Exercises

Exercise 1: Hoisting Behavior of var, let, and const

Test the behavior of var, let, and const in this code snippet:

console.log(myVar); // undefined
var myVar = 1;

console.log(myLet); // ReferenceError
let myLet = 2;

console.log(myConst); // ReferenceError
const myConst = 3;

Exercise 2: Function Declaration vs. Function Expression

Write the following code and explain the results:

console.log(declaredFunc()); // "I am declared"
console.log(exprFunc());     // TypeError: exprFunc is not a function

function declaredFunc() {
  return "I am declared";
}

var exprFunc = function() {
  return "I am an expression";
};

7. Conclusion: Mastering Hoisting in JavaScript

Understanding how hoisting works in JavaScript is critical to avoiding errors and writing predictable code. Whether you're working with var, let, const, or functions, knowing how they behave under hoisting helps you avoid common pitfalls. Remember to always declare your variables at the top of the scope and use let and const to reduce the risk of hoisting-related bugs.


0
Subscribe to my newsletter

Read articles from Piyush kant directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Piyush kant
Piyush kant