Access variables and functions even before initialization ๐ฑ: JavaScript Hoisting
Making impossible possible ๐
Preface
Before diving deep into this blog, I may assume that you had already read my blog on Javascript in action: Under the hood ๐ง and understood it for a better understanding of this blog.
Making impossible possible ๐
How would you feel if you get to access a variable or function even before your code has initialized it? That would feel something weird, right? But yes, that's also possible with JavaScript. JavaScript's peculiar behavior has amazed developers from time to time. Even I was amazed when I got introduced to JavaScript for the first time ๐ . Let's get back to the topic.
Taking an example say,
var a = 10;
function greet () {
console.log("Hi there! Nice to meet you");
}
console.log(a);
greet();
The output would look something like this. No, I'm not kidding. Now, let us see another variant of the same code.
console.log(a);
greet();
var a = 10;
function greet () {
console.log("Hi there! Nice to meet you");
}
Being any other programming language, it would either throw an error or output some garbage values. But JavaScript gives output like -
Okay, so JavaScript cannot access the value of a
and gives undefined
and somehow it got access to the greet
function and logs the output. Now let me modify the code a bit and view its output.
console.log(a);
greet();
function greet () {
console.log("Hi there! Nice to meet you");
}
This is strange. Previously, it gave undefined
and now it gives ReferenceError
.
The reason is that we know, that in the memory allocation phase all variables and functions are allocated space. Hence, when we tried to access the value of a
before JavaScript has come across its initialization in the code, it accessed the value from the variable environment which has a special placeholder named undefined
, and outputs it. On the other hand, when the initialization of a
was removed from the code, JavaScript does not have access to a
variable as it was not even present in the variable environment and throws ReferenceError
.
In the case of functions, we know, that the whole function code is allocated as a value in the variable environment. So invoking it from anywhere in the program will give the output. Now, let me again modify the code a bit and see its behavior.
greet();
greetShort();
function greet () { //function declaration
console.log("Hi there! Nice to meet you");
}
var greetShort = () => { //function expression
console.log("Hi there!");
}
var greetShortest = function () { //function expression
console.log("Hi!");
}
It is to note that hoisting only works for function declaration (only possible with the function
keyword), and not for function expression (can be both with the function
keyword or arrow
) and is considered as variables and hence, allocated with undefined
in the memory allocation phase. So invoking that function would throw ReferenceError
. This is what Global Execution Context (GCE) looks like at this point.
Wrapping up
This is all about hoisting in JavaScript. It is quite important to have a clear concept of under the hood work of JavaScript for any web developer out there. Hope this article was helpful ๐. If so, then do give a reaction and share with others. Want to add something? Write it down in the comments ๐