Encircling the Execution Context 🚩
Brief overview ✨
This blog is with regards to enlightening the most beautiful and the most important feature of JavaScript. Hoisting is one of the most favorite concepts of any interviewer in JavaScript interviews. At the end of the blog, we’ll be able to see what exactly is an Execution context and how everything goes in the backend when we deal with functions, variables, or classes.
Execution context ✨
For an instance, just suppose that execution context is nothing but an area where JavaScipt performs code evaluation and execution. Whenever any code is run in JavaScript, everything happens inside an execution context.
One thing we should always remember when we talk about execution context, i.e. In JavaScript, everything happens inside an execution context. Execution context comprises of two phases, namely Variable environment and Thread of execution/Code execution.
Two phases of execution context ✨
As we learned in the above section, mainly we’ve two phases which are Variable environment and Thread of execution/Code execution.
- Variable environment
The initial phase in the Execution context, where it allocates memory to variables and stores everything in key-value pairs that are in the form of objects. Soon, we’ll see a code snippet and a pictorial representation of how everything goes in and out.
- Thread of execution
The second most phase is in the Execution context, where each code statement is executed one-by-one as per the JavaScript’s usual behavior (synchronous and single-threaded).
Behind the scenes ✨
Let’s see how everything is happening under JavaScript behind the hood using a code snippet, it’s down there.
console.log(x); //prints: undefined
printHere(); //prints: Fun Learning hoistingconsole.log(printHere); //prints: the whole function body in the form of object valuefunction printHere(){
console.log("Fun learning hoisting");
}var x = 10;
console.log(x) //prints: 10 (as expected)
For the above code, let’s see how everything is carried out in an Execution Context when the code is run with a beautiful pictorial representation.
As we can see in the above representation, in phase 1 i.e the variable environment the memory allocation for the variables and function is done. Also in the memory, everything is stored in key-value pair i.e in the form of objects.
So, in phase 1 initially, when we declare any variable using the var keyword, the variable is assigned with an undefined value. So, we can say that in a variable environment the variables, functions, or classes are hoisted in the memory, and variables with var are initialized with undefined while let & const variables are assigned no values and will throw a reference error upon accessing it prior to its the definition. Functions are stored as key-value pairs in such a way that the name of the function is the key whereas the function body is stored as an object value
And finally, in phase 2 which is also known as Thread of execution, all the statements are executed line by line as per usual JavaScript behavior of being synchronous and single-threaded.
Conclusion ✨
You would’ve never seen this kind of weird behavior in any programming languages such as C/C++, Java, etc. If you try to do so, you’ll run into a reference error of referencing a variable before its declaration. But, JavaScript doesn’t throw such kinds of errors on you as it just lets you access anything before its definition as everything is hoisted on the top. Usually, because JavaScript is a modern language and the whole browser is built upon Js.
Quick fun fact ✨
Do you even know that undefined and not defined are different?
So, when your variable declared with keyword var is hoisted it’s assigned a special value undefined and it consoles the same upon accessing it before the definition as we saw above. But if we don’t declare the variable itself nothing is hoisted and upon accessing we get a reference error saying that the particular variable is not defined.