Hoisting

Introduction

Hoisting is one of the most important concepts in JavaScript. It is JavaScript’s default behavior of moving declarations to the top of their scope before the code is executed.

Because of hoisting, variables and functions can sometimes be used before they appear in the source code. However, the behavior differs depending on whether the variable is declared using var, let, or const, and whether the function is a function declaration or a function expression.

Understanding hoisting helps developers avoid unexpected bugs and write more predictable code.

For automation engineers, understanding hoisting is useful when organizing reusable utility functions, page objects, API helper methods, and test scripts.


What is Hoisting?

Hoisting is JavaScript’s behavior of processing declarations before executing the code.

It is important to remember that:

  • Declarations are hoisted.

  • Initializations are not hoisted.

This means JavaScript knows about a variable or function before reaching its declaration, but variable assignments happen only when execution reaches that line.


Variable Hoisting with var

Variables declared with var are hoisted and initialized with undefined.

console.log(message);

var message = "Hello";

Output

undefined

JavaScript internally treats it approximately like this:

var message;

console.log(message);

message = "Hello";

Variable Hoisting with let

Variables declared with let are hoisted but are not initialized immediately.

console.log(message);

let message = "Hello";

Output

ReferenceError: Cannot access 'message' before initialization

This happens because the variable is in the Temporal Dead Zone (TDZ) until its declaration is executed.


Variable Hoisting with const

const behaves similarly to let.

console.log(language);

const language = "JavaScript";

Output

ReferenceError: Cannot access 'language' before initialization

The variable remains in the Temporal Dead Zone (TDZ) until the declaration is reached.


Function Declaration Hoisting

Function declarations are fully hoisted.

They can be called before they appear in the code.

greet();

function greet() {

    console.log("Hello!");

}

Output

Hello!

This is because the entire function declaration is available before execution begins.


Function Expression Hoisting

Function expressions assigned to variables are not fully hoisted.

greet();

var greet = function () {

    console.log("Hello!");

};

Output

TypeError: greet is not a function

Explanation:

  • The variable greet is hoisted.

  • Its value is initially undefined.

  • The function is assigned later during execution.


Arrow Function Hoisting

Arrow functions behave like function expressions.

greet();

const greet = () => {

    console.log("Hello!");

};

Output

ReferenceError: Cannot access 'greet' before initialization

Since const is in the Temporal Dead Zone, the function cannot be called before its declaration.


Hoisting Example

console.log(number);

var number = 10;

console.log(number);

Output

undefined
10

The declaration is hoisted, but the assignment occurs later.


Real-World Example

Display the application name.

showApplication();

function showApplication() {

    console.log("Inventory System");

}

Output

Inventory System

Function declarations can safely be called before they appear in the file.


Another example:

console.log(browser);

var browser = "Chrome";

Output

undefined

Automation Testing Example

Hoisting is commonly encountered when organizing helper functions and utility methods.

Playwright Example

Function declaration.

launchBrowser();

function launchBrowser() {

    console.log("Launching Chromium");

}

Output

Launching Chromium

Selenium Example

Helper function.

openApplication();

function openApplication() {

    console.log("Opening Application");

}

Output

Opening Application

Cypress Example

Using let.

console.log(environment);

let environment = "QA";

Output

ReferenceError

API Testing Example

Using var.

console.log(statusCode);

var statusCode = 200;

Output

undefined

Data-Driven Testing Example

Function declaration.

loadTestData();

function loadTestData() {

    console.log("Loading Data");

}

Output

Loading Data

Temporal Dead Zone (TDZ)

The Temporal Dead Zone (TDZ) is the period between entering a scope and executing the declaration of a let or const variable.

During this period, accessing the variable results in a ReferenceError.

Example:

console.log(name);

let name = "John";

Output

ReferenceError

Hoisting Summary

Declaration TypeHoistedInitializedCan Be Used Before Declaration?
varYesundefinedYes (returns undefined)
letYesNoNo (ReferenceError)
constYesNoNo (ReferenceError)
Function DeclarationYesYesYes
Function Expression (var)Variable onlyundefinedNo (TypeError)
Arrow Function (let / const)Variable onlyNoNo (ReferenceError)

Common Mistakes

Assuming var Keeps Its Value Before Declaration

console.log(total);

var total = 100;

Output

undefined

The declaration is hoisted, not the assignment.


Accessing let Before Declaration

console.log(user);

let user = "Admin";

Output

ReferenceError

Calling an Arrow Function Before Declaration

calculate();

const calculate = () => {

    console.log("Done");

};

Output

ReferenceError

Expecting Function Expressions to Behave Like Function Declarations

display();

var display = function () {

    console.log("Hello");

};

Output

TypeError

Best Practices

Declare Variables Before Using Them

Even though JavaScript hoists declarations, always declare variables before they are used.


Prefer let and const

Using let and const helps avoid bugs caused by var hoisting.


Use Function Declarations for Reusable Utilities

Function declarations can safely be called before they appear in the file, making them useful for reusable helper functions.


Avoid Relying on Hoisting

Write code in the order it executes. This improves readability and reduces confusion.


Conclusion

Hoisting is JavaScript’s mechanism of processing declarations before code execution. While variables and functions are hoisted, their behavior depends on how they are declared.

  • var is hoisted and initialized with undefined.

  • let and const are hoisted but remain in the Temporal Dead Zone until their declarations.

  • Function declarations are fully hoisted.

  • Function expressions and arrow functions are not callable before their assignments.

For automation engineers, understanding hoisting helps organize helper methods, utility functions, and reusable code while avoiding common errors caused by variable declarations.


Frequently Asked Questions (FAQs)

What is hoisting in JavaScript?

Hoisting is JavaScript’s behavior of processing declarations before executing code.


Is variable initialization hoisted?

No. Only declarations are hoisted.


Why does var print undefined?

Because var is hoisted and automatically initialized with undefined.


Why do let and const throw a ReferenceError?

They remain in the Temporal Dead Zone (TDZ) until their declarations are executed.


Can function declarations be called before they are declared?

Yes.

greet();

function greet() {

    console.log("Hello");

}

Why are function expressions and arrow functions different?

Only the variable declaration is hoisted. The function assignment happens later during execution.


Why is hoisting important in automation testing?

Automation engineers need to understand hoisting to organize reusable helper methods, utility functions, page objects, API utilities, and test scripts correctly while avoiding runtime errors caused by accessing variables or functions before they are initialized.


Key Takeaways

  • Hoisting moves declarations to the top of their scope before execution.

  • Variable assignments are not hoisted.

  • var is hoisted and initialized with undefined.

  • let and const are hoisted but remain in the Temporal Dead Zone (TDZ).

  • Function declarations are fully hoisted and can be called before they appear.

  • Function expressions and arrow functions cannot be called before assignment.

  • Avoid relying on hoisting for cleaner and more maintainable code.

  • Prefer let and const in modern JavaScript.

  • Write code in the order it executes to improve readability.

  • Understanding hoisting is essential for writing reliable JavaScript and automation testing scripts.