Different Behaviours of Variable Hoisting and Function Hoisting in JavaScript

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

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.