Before going into the definition of hoisting, let's consider these examples. What do you expect would be the answer to these questions?
Example 1
a = 10;
var a;
console.log(a);
Error? undefined? hmm, no. The output is 10.
What about the below example?
Example 2
console.log(a);
var a = 10;
10, as it would follow the same pattern as example 1? NO
Here a is undefined.
Okay, so, now let's understand what is happening.
Hoisting Definition
Hoisting refers to the process whereby all the declarations are moved to the top of the scope before code execution. An important keyword here is "scope", we will understand later in the blog what it signifies.
Going back to the first example, the declaration will move to the top. Example 1 will be handled like below and so we get the output 10.
var a;
a = 10;
console.log(a);
The second example will be handled like below and thus the output is undefined.
var a;
console.log(a);
a = 10;
In hoisting, not only variable declarations are moved to the top but also functions, classes etc.
Example 3
foo();
function foo() {
var a = 10;
console.log(a);
}
It would be handled like:-
function foo() {
var a = 10;
console.log(a);
}
foo();
Consider another example:-
Example 4
foo();
function foo() {
console.log(a);
var a = 10;
}
the output will be a is undefined.
The above example will be handled like this:
function foo() {
var a;
console.log(a);
a = 10;
}
foo();
The a will move to the top of its scope and not the global scope, so we got a as undefined.
Function expression hoisting
Function expressions are not hoisted only function declarations are:-
foo();
var foo = function bar() {
var a = 10;
console.log(a);
};
The above example would be handled like this:
var foo;
foo();
foo = function bar() {
var a = 10;
console.log(a);
};
We would get a TypeError here. The variable foo will be hosted but not the function bar. The foo would not know of the function bar giving TypeError.
Functions are hoisted first
bar(); // Function
var bar;
function bar() {
console.log("Function");
}
bar = function() {
console.log("Variable");
}
It will be handled like:-
function bar() {
console.log("Function");
}
bar();
bar = function() {
console.log("Variable");
}
The bar declaration was repetitive so was ignored.
Javascript ES6
The Javascript ES6 introduces keywords let and const. Lets understand how hoisting works for them.
console.log(a);
let a = 10;
If you expected the output to be undefined, you understood the hoisting for var variables, but in this case, it is incorrect.
The above throws the error:-
Uncaught ReferenceError: Cannot access 'a' before initialization
So, the let
variables aren't hoisted, no, it's not like that.
Variables declared using let
and const
are hoisted, however, they are not initialized with a default value during hoisting. This means that if you try to access such a variable before it has been initialized in the code, JavaScript will throw a ReferenceError
, indicating that you cannot access the variable before it has been initialized.
This is termed a “Temporal Dead Zone”, A period between variable creation and its initialization where they can’t be accessed.
On the other hand, variables declared with var
are hoisted with a default initialization of undefined, So, if you access them before it is initialised, it gives undefined.
If you like my post, please give it an upvote and follow. :)
Also, do follow my Twitter page, twitter.com/DevTalesShrey where I post articles related to coding regularly.