Understanding Hoisting and Scoping in Javascript

Komolafe Tolulope
Backticks & Tildes
Published in
4 min readFeb 19, 2018

There are several times Javascript developers want to tear their hair out because of an unexpected behavior in their code. Most of these bugs could be traced to these two concepts, Scoping and Hoisting.

Scoping

Scoping is determining where variables, functions, and objects are accessible in your code during runtime. This means the scope of a variable(where it can be accessed) is controlled by the location of the variable declaration.

In Javascript, there are two scopes:

  1. Global Scope
  2. Local Scope

Global Scope

There is only one Global scope throughout a JavaScript document. A variable is in the Global scope if it’s defined outside of a function.

You can also access and alter any variable declared in a global scope from any other scope.

Local Scope

Variables declared within a function are in the local scope. Local scope is also called function scope because local scope is created by functions in Javascript. Variables in the local scope are only accessible within the function in which they are defined, i.e they are bound to their respective functions each having different scopes. This allows us to create variables that have the same name and can be used in different functions.

Variable Shadowing

In JavaScript, variables with the same name can be specified at multiple layers of nested scope. In such case local variables gain priority over global variables. If you declare a local variable and a global variable with the same name, the local variable will take precedence when you use it inside a function. This type of behavior is called shadowing. Simply put, the inner variable shadows the outer. This is how the Javascript interpreter finds a particular variable; it searches for the variable at the innermost scope being executed at the time, and continues until the first match is found, even if there are other variables with the same name in the outer scope.

Another way of declaring variables with a local scope is via block functions. Prior to the introduction of let and const in ECMAScript 6, we couldn’t declare local scope in block statements like for loops

Hoisting

We already know that any variable declared within a scope belongs to that scope. But what we don’t know yet is that no matter where variables are declared within a particular scope, all variable declarations are moved to the top of their scope (global or local). This is because of a concept called Hoisting.

Hoisting in JavaScript is a feature in which the interpreter moves the function and variable declarations to the top of their containing scope. It means that variable declarations, wherever they occur, are processed before any code is executed. Note that hoisting only moves the declaration and not the assignment. This will be clearer in the examples below.

You might have expected the first line to throw an error since the variable is not yet declared or you expected the console.log statement to print out undefined but this is what hoisting does, it essentially interprets the code as :

You can see that the variable declaration is hoisted to the top of the global scope.

Let’s consider this other block of code:

You might wonder why item is not defined when it’s printed. Isn’t item supposed to be hoisted? Well, remember I said only the declarations not the assignments are hoisted. To make this clearer, let’s see how javascript interprets the code:

You can see that the declaration of item is processed first.

Function declarations can also be hoisted:

In the block of code above, while the function is being called before it’s declared, because of hoisting, the function declaration is hoisted to the top of the scope therefore making it possible for the function to be called.

You can see how easy it is to make some mistakes because rather than being available right after their declaration, variables and functions might actually be available beforehand in the code, which might lead to certain behaviors that you wouldn’t expect if you knew nothing about hoisting.

Conclusion

To avoid these mistakes, remember these:

  • All declarations, both functions and variables, are hoisted to the top of the containing scope, before any part of your code is executed.
  • Functions are hoisted first, and then variables.
  • Function declarations have priority over variable declarations, but not over variable assignments.
  • Declare all of your variables at the top of their scope (at the top of the global scope or at the top of the function scope)
  • Make sure you put all your functions, if you can, also at the top of their scope.

If this was helpful in anyway, feel free to comment and like this article so that others can find it easily.

--

--

Komolafe Tolulope
Backticks & Tildes

Software Developer at Andela, soccer enthusiast, Evangelist for gender equality