Different Behaviours of Variable Hoisting and Function Hoisting in JavaScript
This is a detailed article explaining how hoisting in javascript works with variables and functions with proper examples to make it easy to understand
Table of contents
Hoisting is a core concept of Javascript. To understand how Javascript works, it is compulsory to understand how ‘hoisting’ in Javascript works. In simple words, Hoisting is the process by which the interpreter appears to move the declaration of functions, variables, or classes to the top of their scope, before executing the code. I will discuss ‘Hoisting’ in-depth, later in another article, today I'm going to discuss how 'hoisting' behaves differently with ‘variables’ and ‘functions’ in Javascript. So let's get started…
✴️🔷 Variable Hoisting:
Let's understand this step by step.
🔹0️⃣ If we try to use a variable without declaring it anywhere in the code, it will show output like this:
console.log(newVariable);
//Output: ReferenceError: newVariable is not defined
🔹1️⃣ Now, if we declare a variable with var
but don't initiate it with a value, it will show this:
var newVariable;
console.log(newVariable);
//Output: undefined
🔹2️⃣ If we console log the variable before even declaring it, it will give the same output.
console.log(newVariable);
var newVariable
//Output: undefined
Now, a question can arrive to your mind that, In both cases, we are console logging the variable without defining it previously, then if the code shown in the first example gives the output ReferenceError
then why this time it is showing undefined
?
Here comes the concept of Hoisting. When we run our code, first the interpreter will create an execution context and this execution context will first scan through all the codes before executing it and will allocate memory for all variables existing in the code. So in the case of 3rd example, our interpreter already knows that there is a variable declared with var
named newVariable
and it will assign its default value undefined
to it, but in the case of the 1st example, there was not any variable existing in the whole code with that name, so it was showing that reference error.
🔹3️⃣ Okay, now let's see another example:
console.log(newVariable); //Output: undefined
var newVariable = 100;
console.log(newVariable); //Output: 100
In this example, we are defining the variable with a value, but still, it is showing the output of undefined
in the first line. Actually, the javascript variable looks through all the variables available in the code before executing it, but it does not hoist the values of the variables. So this code will execute like this:
var newVariable;
console.log(newVariable); //Output: undefined
newVariable = 100;
console.log(newVariable); //Output: 100
🔹4️⃣ When we declare the same variable multiple times in different scopes, it will behave differently. Let's see some examples:
var name = "Subham";
function printName(){
var name = "SubhamDutta"
console.log("Inner scope Output:", name);
}
printName()
console.log("Outer scope Output: ", name);
//Output:
//Inner scope Output: SubhamDutta
//Outer scope Output: Subham
Here we first declared the variable name
in the global scope and then declared it again in the function scope. So when we are calling the function, it will show the output value from the declared value within the function, but when we console log this variable out of the function, it will render value from the global scope.
- If we don't define the value of
name
within the function scope in this example, it will still use the value from the global scope, because javascript can use variables from the outer scope.
var name = "Subham";
function printName(){
console.log("inner scope Output:", name);
}
printName()
console.log("Outer scope output: ", name);
//Output:
//Inner scope Output: Subham
//Outer scope Output: Subham
- If we only define the value of
name
in the function scope but not in the global scope, in output, the outer scope value will be undefined because js can only render values of variables from the same or upper-level scopes, not from the lower-level scope.
function printName(){
var name = "SubhamDutta"
console.log("inner scope Output:", name);
}
printName()
console.log("Outer scope output: ", name);
//Output:
//inner scope Output: SubhamDutta
//console.log("Outer scope output: ", name);
// ^
//ReferenceError: name is not defined
✴️🔷 Function Hoisting:
So all tricky parts of variable hoisting are already covered, but what about variable hoisting? Though both of them are called 'hoisting', they are quite different from each other. Let's discuss variable hoisting in detail…
🔹0️⃣ Unlike variables, a function declaration doesn't just hoist the function's name. It also hoists the actual function definition. Let's see this with an example:
sayName()
function sayName(){
console.log("Bond, James Bond");
}
//Output: Bond, James Bond
Here we are calling the function before declaring it and still it is showing the output. This means the js interpreter hoists through the whole function, not only the function name as it does with variables.
🔹1️⃣ Function definition hoisting occurs only for function declaration, not for function expression. Example:
lastName()
fullName()
function lastName(){
console.log("Bond");
}
var fullName = function(){
console.log("James Bond");
}
//Output: Bond
//TypeError: fullName is not a function
Here lastName
is declared as function, so it is getting hoisted and showing the expected result, but the function fullName
is declared as a variable, so the interpreter is reading this as a variable, thus can render before declaration. If we remove the function call fullName
from the top and call that function after declaration, it will render properly.
With this, we have discussed almost every strange behavior of variable and function hoisting. If you want to add something or give feedback, please leave your comment below.
Thanks for reading. Happy learning.