Assume you are talking with a friend and they ask you about something that you know nothing about. Your response would be "I do not know about that".
In the same way, during execution, our program needs to know about the variables we refer to or else we might get an error.
var age = 12; // line 1
console.log(age); // line 2
Line 1: Create a variable called age and give it the value 12.
Line 2: Get the value of age and log it to the console.
console.log(age); //line 1
var age = 12; //line 2
Line 1: Get the value of age and log it to the console.
Line 2: Create a variable called age and give it the value 12.
When we run this program (logically speaking), we would expect to get an error because, at line 1, we are already asking for something the compiler doesn't know about yet because it hasn't gotten to line 2 in its execution, but against our logical reasoning, we will discover that this code will run without an error. This code runs without an error because of the concept of hoisting and how variables created with the var keyword behave.
As our usual practice, let's seek to understand the term "hoisting" by examining the word used to coin it.
The construct of the word tells us that it refers to an action taking place but what is the name of the action?
To hoist means to raise something. Hoisting is the process of doing just that 😉
Hoisting can be loosely described as the process of raising variables to the top of their context before the context execution so that every code using (or referring to) that variable will have access to it irrespective of the line in which the code exists in the context. That is why the code written in SNIPPET 2 above could run. This is not something to celebrate until you have sufficient knowledge of what's going on behind the scene.
Do you recall from this article that during the creation phase of an execution context, all variable and function declarations are put in memory and assigned a value of undefined? Let me explain what that "memory" is all about.
The memory that is created during the creation phase of an execution context is called a variable object.
In the Global Execution context, it is the Global and/or Script object. While in the function execution context, it is commonly referred to as Activation Object.
Let's put all this knowledge so far together;
Using SNIPPET 2 as a case study, when our program runs, during the creation phase of the global execution context, a memory is created and then the variable age is attached to it with an initial value of undefined
Remember that in the creation phase of an execution context, all variable and function declarations are taken note of. We can dare to say they are hoisted.
The consequence of this phase is that the program now knows about the variable age. Therefore, when the execution phase begins and at line 1 we attempt to access the value of age, we'll get undefined because at that point in the execution phase of the program, the variable has not been assigned a value yet. It merely just exists in memory with a default value.
After line 2, if we try to access the variable again, we'll now get its actual value.
So conceptually, during the creation phase of an execution context, all variable and function declarations are raised to the top of the context so that they are accessible from any line during the execution phase of that context.
There are some persons with the idea that variables are only hoisted when created with the var keyword (fair point) but I'd like to state that all keywords support hoisting.
The way I think about it is that the keyword we choose to use when creating variables simply affects how they are accessed in the program.
One major difference between the behaviour of variables created with var and those created with let or const; is that accessing variables created using the let or const keyword can only be done after the actual line where they were declared physically in the code. That is, you cannot access variables created with the let or const keyword before they are declared.
The code in the snippet below will result in an error.
console.log(age); // ReferenceError
let age = 12;
Why do I disagree with the idea that variables created using the let or const keyword isn't hoisted?
This is because, during the creation phase of the context where they exist, they are still put in memory and assigned a value of undefined.
That memory is logically located at the top-most of its context making them accessible by child-contexts and child-scopes.
In the global context, a variable created with the let or const keyword is stored in a type of variable object called Script. Those created with the var keyword are stored in a variable object called Global. While in the function context, all variables are stored in the functions' Activation Object.
NB: Do not get too concerned about the meaning of the term variable or activation object. They are simply conceptual terms to refer to a place in a context where variables created in that context are stored.
According to MDN docs, any of the following behaviours can be regarded as hoisting;
All the above-stated behaviours are obtainable at the creation phase of a context.
People mostly associate the term hosting to the var keyword but the truth is that even variables created using the var keyword are not listed in the ECMAScript Specification as hoistable declarations.
Hoisting is just an adopted term to describe what happens during the creation phase of an execution context when variables are put in memory and assigned a default value of undefined.
Variables created with the var keyword can be referenced from any line even before the line where they are defined, but trying to reference variables created using the let or const keyword before the line where they are physically declared in the program will result in a referenceError.
If this article was helpful to you in any way, kindly like and share (you can like up to 10 times). I'll be glad to engage your questions in the comment section ❤️
From physical tools to specialised software, being equipped with the right resources is crucial in maximising the....