loading...

Hoisting in JavaScript

asim_ansari7 profile image Asim ・3 min read

Demystifying one of the quirks of the language.

This article is originally posted here.

Consider the following code sample

var myName = "Bruce Wayne"  
function getCity(){  
   console.log("Gotham");  
}  
console.log(myName);  
getCity();

Executing the code will return Bruce Wayne and Gotham which was kinda expected.

To make things interesting, try running the following code:

console.log(myName);  
getCity();  
var myName = "Bruce Wayne"  
function getCity(){  
   console.log("Gotham");  
}

In most programming languages this would throw an error as code is executed line by line. But with Javascript that's not the case, upon execution, the output will be Gotham and undefined.

And you are introduced to one of the many quirks in the language. This phenomenon is known as hoisting.

If you look up for the term Hoisting online, in many places it is explained as if the variables and functions in JS are moved to the top by the JavaScript Engine

To gain a bit more understanding and why this happens we need to dive into the Execution Context and how it is created.

What is an Execution Context?

Execution context (EC) is defined as the environment in which the JavaScript code is executed. It contains properties that you haven't even declared in your code. If you run the above code in the browser and open the console window, you get access to the window object as well as the this keyword. These were added by the JS Engine and for the Global Execution Context which is the default execution context they are the same thing. Similarly, we have a Functional execution context which is created by the JS engine whenever it finds any function call. Each function has its own execution context. In layman terms, global is something which is not inside any function, so in the code above, the variable myName and function getCity get attached to the global scope.

Execution Context in Detail

An execution context is created in two-phase by the interpreter.

  1. Creation Phase

    creation phase

    The Global object is created only when we are dealing with the Global Execution Context, the this keyword is always created in an execution context. In this phase, the parser identifies the variables and the functions created in code and sets up memory space for it which is confusingly called hoisting . So when the code is run line by line it can actually access them. However, things work differently for variables and functions. A function is entirely placed in memory with all the code inside of it, while all variables are set to undefined in the first phase.

  2. Execution Phase

    This phase is pretty simple, in this phase code is run line by line, interpreting it and executing it on the computer.

    Consider the following code sample:

    function getCity(){  
       console.log("Gotham"); 
    }  
    getCity();  
    console.log(myName);  
    var myName = "Bruce Wayne"  
    console.log(myName);
    

    Upon execution, we get Gotham, undefined, and Bruce Wayne. And this would now be clear as to when we log myName before it's initialization it is actually set to undefined in the creation phase.

I hope, you got a grasp about how the JavaScript interpreter is evaluating your code and you could avoid possible unexpected behavior in the future.

Discussion

pic
Editor guide