In this part of the series, we'll learn about one of the important concepts of Javascript: Hoisting.
Hoisting
Hoisting is a JavaScript mechanism where variables and function declarations are moved to the top of their scope before code execution.
Inevitably, this means that no matter where functions and variables are declared, they are moved to the top of their scope regardless of whether their scope is global or local.
Hoisting mechanism only moves the declaration and not assignment.
Let's try to understand this using an example:
Variable Hoisting using "var"
console.log(example);
var example = "hoisting example";
For the above snippet, Output will be:
So, exactly what happens is JS executed the above code in two phases:
- Memory Creation Phase
- Code execution Phase
If you are not aware of these terms, I'll highly recommend you to read this article.
During Memory Creation Phase, it assigns special value undefined
to the variables.
var is hoisted on top of its scope and hence is undefined
.
Now, if we tried to run the below code:
console.log(example);
var example = "hoisting example";
console.log(example);
The output will be:
As you might expect, the second log() function logs the actual value because, during the code execution phase, it initializes the variable "example" with the value "hoisting example".
Variable Hoisting using "let"
Now consider the same example but instead of var, this time we use let.
console.log(example);
let example = "hoisting example";
Output for this will be:
What why?? I expected it to be undefined.
let was introduced in ES6 and doesn't allow the use of undeclared variables, the interpreter explicitly spits out a Reference error.
This ensures we always declare our variables before using them.
Now if we modify our code like this:
let example;
console.log(example);
example = "hoisting example";
console.log(example);
This works exactly what we expected.
Variable Hoisting using "const"
Consider the below code:
console.log(example);
const example = "hoisting example";
Output for this will be:
It works the same way as let if used before declaring.
Another scenario for const:
const example;
console.log(example);
Output:
Since const is an immutable
type it should be defined when it's declared.
So, the correct way to work with const is:
const example = "hoisting example";
console.log(example);
Hoisting in Function Declaration
console.log(example);
example();
function example(){
console.log("This is example function output")
}
A function declaration is hoisted completely to the top. Now, we can understand why Javascript enables us to invoke a function before declaring it.
Hoisting in Function Expression
console.log(example);
example();
var example = function() {
console.log("This is example function output")
}
So why is it working in the function declaration but not in function expression?
Function expressions are not hoisted.
The interpreter throws a TypeError since it sees expression as a variable and not a function (only variable declaration is hoisted).
A function expression is a function that is assigned to a variable, and, in this case, the variable declaration is moved to the top with the default value of undefined rather than the function.
Hoisting in Arrow Functions
Arrow functions are a more compact way of writing function expressions in javascript.
console.log(example);
example();
var example = () => {
console.log("This is example function output")
}
It follows the same hoisting rules as that of function expressions.
Wrap Up
Thanks for reading!! I hope it was helpful to some extent. Please share it with your network. Don’t forget to leave your comments below.