Sitemap

Understanding JavaScript Hoisting: The Magic Behind Variable and Function Declarations

4 min readDec 5, 2024

--

If you’ve ever come across a piece of JavaScript code where variables or functions are used before being declared, you might have scratched your head wondering how that even works. Well, that’s the magic of hoisting!

What is Hoisting?

Hoisting is a JavaScript mechanism where variable and function declarations are moved (or “hoisted”) to the top of their scope before any code execution takes place. This means that no matter where you declare a variable or a function, JavaScript internally shifts those declarations to the top of the scope in which they are defined, whether it’s a global scope or a local scope.

console.log(x); 
var x;
//output: undefined

When JavaScript runs this code, it first hoists the declaration of the variable x to the top of the scope. Since x is declared but not yet assigned a value, its value is undefined when console.log(x) is executed.

console.log(y);
var y = 5;

JavaScript hoists the declaration of the variable y to the top of the scope, but only the declaration (y) is hoisted, not the initialization (y = 5).

JavaScript treats your code as if it were written like this:

var y; // Declaration is hoisted
console.log(y); // undefined
y = 5; // Initialization happens later

let and const are not hoisted in the same way as var:

Unlike var, let and const are not hoisted in a way that allows them to be accessed before their declaration, because of a concept called the Temporal Dead Zone (TDZ).

The Temporal Dead Zone (TDZ) is the time between entering the block scope where a variable is declared and when it is initialized.

During this period, if you try to access the variable, you’ll get a ReferenceError. This happens because, even though the variable’s declaration is hoisted to the top, it cannot be accessed until it’s initialized.

The TDZ helps prevent bugs by stopping the use of uninitialized variables.

Why Does This Happen?

var is either function-scoped or globally scoped, meaning it gets moved to the top and automatically set to undefined. This gives flexibility to declare variables anywhere in the scope but can cause problems, like using a variable before it’s assigned a value.

Both let and const are block-scoped, meaning they are only available within the block they are declared. Unlike var, they are moved to the top but not assigned a value until the actual line of declaration. Trying to use them before that will cause an error.

Hoisting with Functions

Hoisting also applies to functions, but with a small difference:

Function Declarations: A function declaration is created using the function keyword and can exist in either the global or local scope. Function declarations are fully hoisted, meaning both the function’s name and its body are moved to the top of their scope. This allows the function to be called even before its declaration appears in the code.

hello(); 

function hello() {
console.log("Hello, world!");
}

//output: // "Hello, world!"

Function Expression: A function expression defines a function and assigns it to a variable. While the variable declaration is hoisted to the top of its scope, the function’s definition or assignment occurs only when the code execution reaches that specific line. As a result, the function cannot be used or called until it is fully defined at that point in the code.

greet(); 
var greet = function() {
console.log("Hello!");
};

//output : // TypeError: greet is not a function

Why Does Hoisting Exist?

Hoisting exists because JavaScript was designed to allow flexibility in how we structure our code. It ensures that all declarations (whether functions or variables) are accessible within their scope, even if they appear after they’re used. However, it’s important to understand how it works to avoid confusion and errors.

Key Points to Remember

Declarations Are Hoisted :
Variables and functions are known to JavaScript before execution begins, but only their declarations are moved to the top of the scope.
Initializations Stay in Place :
While declarations are hoisted, values aren’t assigned until the interpreter reaches the initialization line. Accessing a variable or function before initialization may lead to unexpected results.
Function Declarations: Fully hoisted, including their body. You can call them anywhere in their scope.
Function Expressions: Only the variable declaration is hoisted, not the function body.
Arrow Functions: Behave like function expressions — only the variable is hoisted, not the function.

Best Practices

  1. Always declare and initialize variables and functions before using them to avoid confusion caused by hoisting.
  2. This keeps your code predictable and easier to debug.
  3. Write clean, organized code by declaring variables and functions at the top of their scope and initializing them as needed. It prevents issues like undefined variables or runtime errors.

Now that you’ve mastered hoisting, you’re all set to write cleaner and more predictable JavaScript code! 🎩✨ Keep experimenting and testing your code to see hoisting in action. The more you practice, the easier it will get — so go ahead, unlock your JavaScript superpower, and let the coding fun begin! 🚀

--

--

Sujitha Kumar
Sujitha Kumar

Written by Sujitha Kumar

I'm a passionate front-end developer. I love sharing insights on web development, Angular, and responsive design. Let's learn and grow together!

No responses yet