What is JavaScript Hoisting. What happens behind JavaScript? [2022]

JavaScript has some crazy concepts that seem like they were invented by aliens. One of them is called “hoisting“. It sounds hard, but hopefully I can explain it to you within this article.

In JavaScript, you can invoke a function before it is declared. This may sound like a crime to you if you come from other programming languages, but it’s not. Many programmers do this and JavaScript does not care. The code will still run.

What is JavaScript Hoisting. What happens behind JavaScript ?

If you’re looking for a JavaScript Hoisting technique, you may have come across this definition: “JavaScript moves declarations to the top by default”.

But what actually happens behind JavaScript ?

Hoisting relates to the process in which the compiler allocates memory for variables and functions before executing code.

Declarations defined using var are initialized with the value undefined by default. Let and const declarations are not initialized as part of hoisting.

Guide To JavaScript Variables and Scopes [2022](Opens in a new browser tab)

Lets see how JavaScript work Behind?

When a JavaScript Code is executed Execution Context is created.

What is Execution Context?

Execution Context is an abstract concept that hold information about environment within which code is being executed. When we run JavaScript Code Execution Context is Created in two phase Memory Creation and Code Execution.

I have already written a detailed explanation on How JavaScript Works Behind The Scenes & Execution Context.

Consider a code block:

var a = 7;
function welcome_message(){
console.log("Welcome to Black Rupee!!");
}
console.log(a);
welcome_message();

Output of this code block will be

7
Welcome to Black Rupee!!

This code will run only once. Memory will be allocated to our variables and functions, but after that, nothing else can be allocated.

When variable ‘a’ is encountered, JavaScript reserves a memory space for it. The value of ‘a’ is then undefined. And for function it will store entire function.

For Example

Let’s Say

console.log(a);
welcome_message();
var a=7;
function welcome_message(){
console.log("Welcome to Black Rupee!!");
}

We are logging ‘a’ and calling function before declaring, we should be getting error but JavaScript works differently like we saw memory is allocated before execution.

Then the output will be:

undefined
Welcome to Black Rupee!!

So that’s how it works. You can use these variables and methods even before they are initialized in your code.

Note: The important distinction between variable hoisting and function hoisting is that a var variable is hoisted and then auto-initialized to undefined whereas a function declaration is hoisted and initialized to its function value.

Function declaration vs Function expression Vs Arrow Functions?

Function hoisting only applies to formal function declarations and not to function expression assignments and arrow functions. Consider:

welcome_message(); // TypeError: welcome_message is not a function
welcome_arrow_function(); // TypeError: welcome_arrow_function is not a function

console.log(welcome_message); // undefined
console.log(welcome_arrow_function); // undefined

var welcome_message = function welcome_message() {
  console.log("Welcome to Black Rupee!!");
};

var welcome_arrow_function = () => {
  console.log("Welcome to Black Rupee Arrow Function")

Above, we can see that the welcome_message,welcome_arrow_function variable are hoisted but it was not initialized with the function reference. The engine throws us a TypeError: welcome_message is not a function and not ReferenceError: welcome_message is not defined. The function expression assignments behave very much like variable hoisting.

What about let and const?

So far, I have only talked about var and formal function declarations. What about the let and const. Let’s see the following code snippet:

console.log(welcome_message); // cannot access 'welcome_message' before initialization
let welcome_message = "Welcome to Black Rupee!!";

This is a brand new error. It’s not a Reference Error; the engine knows about welcome_message, but won’t let you use it until it’s been declared. This is called the Temporal Dead Zone, and it stops you from accessing variables declared with let and const before they’ve been declared.

let welcome_message;

console.log(welcome_message); // undefined

welcome_message = "Welcome to Black Rupee!!";

Above, we can see that we are able to access the welcome_message variable as soon as it was declared.

So, let and const are not hoisted?

After examining the two code samples above, I was also satisfied that let and const are not hoisted. However, they do exist. We can demonstrate this with a few more examples –

console.log(typeof iDontExist); // undefined
console.log(typeof welcome_message); // cannot access 'welcome_message' before initialization

let welcome_message = "hello";

If the welcome message variable was not hoisted, typeof welcome message would be undefined, similar to typeof iDontExist. This demonstrates that the JS engine is aware of our welcome message variable but is preventing us from accessing it owing to the Temporal Dead Zone.

let x = 'outer value';
console.log(x); // outer value
 {
  // start Temporal Dead Zone for x
  console.log(x); // cannot access 'x' before initialization
  let x = 'inner value'; // declaration ends TDZ for x
 }

Trying to access the variable x in the inner scope still results in the Temporal Dead Zone error. If the let x = ‘inner value’; was not hoisted, it would have recorded outer value on line 6.

Conclusion

  • The var declarations are hoisted and set to undefined.
  • The formal function declarations are hoisted and their function references are initialized.
  • Variables such as let and const are also hoisted, but they cannot be accessed before their declarations. This is known as the Temporal Dead Zone.

Thanks for reading.

Share your love

Leave a Reply