Let's Understand JS 02 -What is hoisting?

Let's Understand JS 02 -What is hoisting?

Let's Understand JavaScript is a series of blogs explaining JS in the simplest way possible, demystifying the jargon on your way.

Hoisting

Before learning hoisting in the right way it's important to unlearn the wrong stuff that's popular around the web. It's not true that variables and functions are moved to the top of the scope before the execution. Let's understand this in a better way!

no

Hoisting is a mechanism by which you can access variables and functions in JS even before they are initialized with any value.

var printName="JavaScript";
function print(){
    console.log("Learning JavaScript");
}

console.log(printName);
print();
console.log(print);

The output of this code is

JavaScript
Learning JavaScript
function print(){
    console.log("Learning JavaScript");
}

It works well and good. So, let's see what happens when we jumble our code.

console.log(printName);
print();
console.log(print);

var printName="JavaScript";
function print(){
    console.log("Learning JavaScript");
}

The output for above is:

undefined
Learning JavaScript
function print(){
    console.log("Learning JavaScript");
}

So as you see, JS prints undefined for the variable declared with var but not an error. Similarly, the function call prints the actual value and when we try to console the function, it prints the whole function itself.

surprise

Not to forget all these happens before the actual variable/function is initialized.

Screenshot (252).png

JS behaves this way because whenever you run a piece of code the execution happens in two phases, in the first phase the variables are allocated memory and initialized with an undefined keyword while the functions are allocated memory and the memory space holds the entire function code as shown in the pic above. And that's the reason behind hoisting!

I highly suggest you read the first blog of this series which explains the creation of execution context to understand hoisting better.

Not defined vars

console.log(something);
var name="JavaScript";

When you try to access a variable that is not defined anywhere in your code in that case, you would end up in the following error because JS checks for that variable in the memory and it wouldn't find that variable.

not defined !== undefined
ReferenceError: something is not defined

Function Declaration with arrow function/ function expression:

A function declaration can be made in 3 different ways: 1) Regular function 2) Arrow function 3) Function expression -> We can assign a function to a variable in JS

console.log(welcome);
welcome();
console.log(welcome2);
welcome2();
welcome();

function welcome(){
    console.log("Helloo");
}

var welcome2 = () => {
    console.log("Helloo from welcome2");
}

var welcome3 = function (){
    console.log("Helloo from welcome3");
}

Screenshot (251).png

When you try to access the arrow function/function expression similar to a normal function, you would end up in an error because JS considers them as variables and assigns undefined to the function during the memory allocation phase.

TypeError: welcome2 is not a function

Let and Const Hoist:

Now, it's time to demystify another truth. What if I say Let and const are hoisted.

wait.What

Yeah, that's true they are hoisted. Let's see how.

let a =10;
const b=20;
function numLogger(){
    console.log(`a= ${a}, b= ${b}`);
}
numLogger();

Screenshot (253).png

So, let and const are not hoisted in global scope but under a reserved space for them which is script here.

So, these variables can be accessed only after their initialization unlike the var declared variable, they are not initialized with default value undefined.As they tend to be in Temporal Dead Zone before they are initialized.

Temporal Dead Zone(TDZ):

TDZ is the phase between which the let/const variables are declared(i.e created) and it is initialized with some value. So, for const TDZ becomes zero as we have to initialize it with some value at the time of creation. Until the line in which they are initialized is executed, accessing them before initialization results in the following error.

Screenshot (255).png

Summary:

Hoisting is a mechanism by which the compiler allocates memory for variable and function declarations before the execution of the code. Hence you can access those variables and functions even before their initialization.

Arrow functions and function expressions will be treated as variables and be assigned with undefined before they are actually executed.

Some variable is not defined is not same as undefined

Let and const variables are also hoisted but unlike for var, the variables are not initialized with a default value of undefined. They can be accessed only after the line in which they are initialized is executed

Yeah, that's all about hoisting !!

done