Just so you know:
Hoisting is a JavaScript mechanism where variables and function declarations are moved to the top of their scope before code execution.
Let's understand the hoisting for different variable declarations and function:
Hoisting of var
var
variables are hoisted to the top of their scope and initialized with a value of undefined
.
console.log(villain); // ReferenceError: villain is not defined
console.log(hero);
var hero;
hero = 'Batman';
console.log(hero);
In the above example, the villain
variable is not declared in the entire code snippet. So console.log(villain)
will throw an error and break the script execution. This means other lines won't execute.
Get rid of the first line console.log(villain)
in the above example and try again:
console.log(hero); // accessing before it was initialized
var hero;
hero = 'Batman';
console.log(hero);
In the above example, we are trying to access hero
variable before it was initialized. So hero
variable here will hoist on top of this scope. Now console.log(hero)
would print undefined
instead of breaking the script execution this time.
This hoisting mechanism works internally so you wouldn't see the code moving like that but internally the above code would turn into something like this:
var hero; // It came on the top automatically (internally)
console.log(hero); // 'undefined'
hero = 'Batman';
console.log(hero); // 'Batman'
Notice the var
in the above examples? Let's change that to let
or const
and see what happens.
Hoisting of let
and const
let
and const
variables are hoisted to the top just like var
variables. But there is a difference - For var
declaration, hoisted variables are initialized as undefined
but that's not the case with let
and const
declaration.
So if we pull up the same examples from the var
declaration:
console.log(hero); // ReferenceError: hero is not defined
let hero;
hero = 'Batman';
console.log(hero);
If you run the above code (we have let
now instead of var
), you will get a Reference Error
. So always initialize your variables before using them.
Hoisting of Functions
Functions are also hoisted on top of the scope just like variables.
// First example
eatCookie();
function eatCookie() {
console.log('Eating 🍪');
}
// Second Example
function eatCookie() {
console.log('Eating 🍪');
}
eatCookie();
The two examples above would work the same because functions with their entire content would be hoisted to the top. So the first example would internally turn into the second example.
But, there is a catch 😁
eatCookie(); // ❌ TypeError: eatCookie is not a function
var eatCookie = function() {
console.log('Eating 🍪');
}
So what happened in the above example?
If you notice, we have not declared a function but an expression that acts like a function. So eatCookie
would hoist to the top as a variable and instead of the function body, it would be initialized with undefined
.
Please note, that this case is valid only if we use var
. But if a function expression is declared using a let
and const
then this would throw a ReferenceError
because let
and const
cannot be initialized like var
variables, just like we discussed earlier.
This is why you should always initialize your variables and functions first, before using them. 🙏
Here is your cookie 🍪 for reading this.