Understanding Hoisting in JavaScript: The Complete Explanation
In this article, we will learn what is hoisting in javascript and how actually it works in the real world.
What is Hoisting?
Just a few microseconds before your code is run, during the compilation phase, it is checked for function and variable declarations.
All these functions and variable declarations are stored in memory inside a JavaScript data structure called Lexical Environment.
So that they can be used even before they are actually declared in the source code.
What is a Lexical Environment?
A lexical environment is a data structure that holds an identifier-variable mapping. (identifier refers to the name of variables/functions, and the variable is the reference to the actual object [including function object] or primitive value).
So, in other words, a lexical environment is a place where variables and functions live during the program execution.
Function Hoisting:
In the Creation phase, all declared functions are moved to the top of their scope
sum(15, 10);
function sum(a, b) {
add = a + b;
console.log(add);
}
//Output: '25' to the console
So in the above code, that function declaration is added to the memory during the compile stage, so we are able to access it in our code before the actual function declaration.
Exception of Hoisting:
Only function declarations are hoisted in JavaScript, function expressions are not hoisted.
For example: this code won’t work.
helloWorld(); // TypeError: helloWorld is not a function
var helloWorld = function(){
console.log('Hello World!');
}
As JavaScript only hoist declarations, not initializations (assignments), so the helloWorld
will be treated as a variable, not as a function. Because helloWorld
is a var
variable, so the engine will assign is the undefined
the value during hoisting.
Variable Hoisting:
Now let's see how it works with variables, see below example:
console.log(sample);
var sample = 7;
// outputs 'undefined'
So, why we get undefined instead of 7?
Because, JavaScript only hoists declarations, not initializations.
JavaScript only keeps the declarations of functions and variables in memory during compilation time, not their assignments (value).
How undefined is set?
The var variable will be added to the lexical environment and initialised with undefined when the JavaScript engine discovers a var variable declaration during the compilation phase.
Later, during execution, when it reaches the line where the actual assignment is made in the code, it will assign that value to the variable.
That’s why we got undefined
instead of 7
Hoisting let and const variables:
See the below example:
console.log(7);
let sample = 7;
//Output : ReferenceError: sample is not defined
Why we got this error?
Because,All declarations (function, var, let and const) are hoisted in JavaScript, while the var declarations are initialized with undefined, but let and const declarations remain uninitialized.
They won't be initialised until the JavaScript engine evaluates their lexical binding (assignment) during runtime.
This means you can’t access the variable before the engine evaluates its value at the place it was declared in the source code.
This scenario is also called a "Temporal Dead Zone", a period of time between the creation of a variable and its initialization during which it cannot be accessed.
Conclusion
So, now we saw how exactly Hosting works in JavaScript, which will assist you in preventing any future hoisting-related issues and misunderstandings.
Always try to declare variables at the top of their respective scopes and always try to initialize variables when you declare them to prevent potential hoisting side effects like undefined variables or reference errors.