20
Javascript Hoisting
Hoisting is one of the important concepts every javascript or its related frameworks developers should be familiar with. Ever wonder how function calls or variable access can be done even before declaring those. If that's so then, Welcome to Javascript Hoisting World!!!.
This is one of the most common interview questions in front end development and common answer will be
All variable and function declarations are moved to top.
Really???😮
Hoisting is not what you think!!!😕
Let us discuss and clarify everything regarding hoisting in today's post.
If you are trying to search and learn about hoisting, almost everywhere you will be seeing the same definition. May be that's beginner friendly but definitely that's not true. In JavaScript, Nothing will be moved.
Let's discuss in detail.
Before we start, let us understand how our code will be executed in javascript engine.
JavaScript engine runs through our code twice. First time (creation phase) - the engine goes through the code and allocates memory for the declarations of variables and functions. Second time(Execution phase) is where it actually executes our code by going through it line by line, doing the assignments, calling the functions and so on..
Variables are one of the fundamental blocks of any programming language, the way each language defines how we declare and interact with variables can make or break a programming language. Thus any developer needs to understand how to effectively work with variables and their properties.
console.log('myName',myName);
var myName = 'JavaScript';
console.log('myName',myName);
If you look at the above example and when you try to run the code, it will not throw error. First one will be undefined
and second one will be Javascript
.
This is because no matter how are declaring variables, Javascript will always go through these lifecycles to declare a variable,
- Declaration
- Initialization
- Utilization.
So,
According to this lifecycle, the above example code will be split into
var myName -> Declaration
myName = 'JavaScript' -> Initialization
console.log('myName',myName); -> Utilization.
So,in the first run javascript will check for the declarations of variables/functions and allocates memory space. This is where all the variables will be declared with a default value undefined
and in the second run while running through all the code it will assign the actual value for it.
Actual definition
Javascript actually scans the code and takes all the variables and allocates separate memory space even before executing the code. Its just variable declarations are executed first, so they will be in reserved memory. MDN.
After introduction of ES6, Variables in Javascript can be declared by three types: var,let and const.
Another misconception is variable declared using var is only hoisted and let and const are not hoisted.
But that's not true. As per definition all the variable and function declarations are hoisted. But let
and const
hoisted a bit different.Let
and const
are hoisted in block scope whereas var
is hoisted in global scope. (Scope is another important concept which we will discuss in future post).
console.log('myName',myName);
let myName = 'Javascript';
If you run the above code, you will be getting an error
Uncaught ReferenceError: myName is not defined.
It's not the same case when you declare variable using var.
Wait how's that??🤔
Here comes a term called Temporal Dead Zone(TDZ).
We are already in a middle of understanding one sci-fi term hoisting, but here comes the another sci-fi term called Temporal Dead Zone 🙄.
So, what exactly is Temporal Dead Zone?
It is Time taken between declaring the variable(using let
or const
) and initializing the variable.
Let's go to the same code and will see why it shows reference error.
/*
let myName;
//Beginning of the temporal dead zone
console.log(firstname); // ReferenceError as accessed in the TDZ.
let myName = 'Javascript'; // Ending of the temporal dead zone
*/
Usage of Let
and const
is recommended because unlike var
, there’s no risk of variable leakage outside of the scope of execution unless if needed. To learn more about var,let and const declarations, Please refer this link
Functions are one of the fundamental building blocks in JavaScript.
There are multiple ways to declare a function. Common ways to declare a functions are
- Function Declaration
- Function Expression
- Arrow Function
Function Declaration
greetings();
function greetings(){
console.log('Hello from dev community')
}
If you run this example it won't throw any error because greetings will be declared on the first run by javascript engine due to hoisting.
greetings();
function greetings(){
console.log('First',message);
var message = 'Hello from Dev Community';
console.log('Second',message);
}
If you run this code, first console will display undefined
because variables declared inside functions will be hoisted only top of the particular scope (code blocks). So the code will be
greetings();
function greetings(){
var message;
console.log('First',message);
message = 'Hello from Dev Community';
console.log('Second',message);
}
Function Expression
greetings(); // Ouput: TypeError: expression is not a function.
var greetings = function hoisting() {
console.log('Hello from function expression?');
};
JavaScript returns a TypeError
because unlike function declaration, only the variable was hoisted. When variables declared with var are hoisted, they are given a default value of undefined
. JavaScript then throws an error because the value of the variable is not a function at that point of time.
Arrow Functions
greetings(); // Ouput: TypeError: expression is not a function.
const greetings = () => {
console.log('Hello from arrow functions?');
};
This works same as function expression due to hoisting.When using arrow functions, or any other function expression, we must always define the function before we call it. Accessing variables before declaration is often a root cause of errors. To clarify
Only function Declarations are hoisted.
Always function declarations are given high priority than variable declarations as per ECMAScript, section 10.5
var abc;
function abc(){}
console.log(typeof abc)
function abcd(){}
var abcd
console.log(typeof abcd)
If you run the above code, no matter what order you declare it, javascript engine will always gives high priority to function declarations than variable declarations.
Let’s summarise what we’ve learned
- Hoisting is a process that declares variables and functions into memory space ahead of assignment and initialization within the given scope of execution.
- Only variable declarations and function declarations are hoisted.
- const and let will be hoisted but cannot be read or accessed before their initialization.
- function declarations are given high priority than variable declarations while hoisting.
To avoid confusion of hoisting and issues, it’s better to declare variables and functions before accessing them. You’ll avoid plenty of bugs and undefined warnings filling your console.
I hope this clarifies how hoisting works in JavaScript. It's definitely not a complicated one as it sounds, but it requires us to breakdown the different use cases and trying different scenarios to understand how things work under the hood.
Thanks for reading this post. Have a great day🙂.
Let's meet on the next post with another Javascript concept.
20