JavaScript: What exactly is Hoisting?
Tags: javascript, beginners, fundamentals, programming
Published: 2023-05-05 02:17:37

Assume you are talking with a friend and they ask you about something that you know nothing about. Your response would be "I do not know about that".

In the same way, during execution, our program needs to know about the variables we refer to or else we ***might*** get an error.

Let's consider two simple code snippets to illustrate how JavaScript executes.

**SNIPPET 1:**

```javascript
var age = 12; // line 1
console.log(age); // line 2
```

**Code Interpretation:**  
**Line 1**: Create a variable called `age` and give it the value `12`.  
**Line 2**: Get the value of `age` and log it to the console.

Notice that in the code snipped above, `var age = 12` is written before `console.log(age)`. JavaScript code executes from top to bottom so it is only reasonable that when **line 2** executes - because we have the variable `age` declared in **line 1** before its usage in **line 2** - there should be no error because having gone through **line 1**, the JS engine understands that **line 2** is simply requesting to log the value of `age` which is declared in **line 1** to the console.

**SNIPPET 2:**

```javascript
console.log(age); //line 1
var age = 12; //line 2
```

**Code Interpretation:**  
**Line 1**: Get the value of `age` and log it to the console.  
**Line 2**: Create a variable called `age` and give it the value `12`.

When we run this program (logically speaking), we would expect to get an error because, at **line 1**, we are already asking for something the compiler doesn't know about yet because it hasn't gotten to **line 2** in its **execution**, but against our logical reasoning, we will discover that this code will run without an error. This code runs without an error because of the concept of **hoisting** and how variables created with the `var` keyword behave.

As our usual practice, let's seek to understand the term "hoisting" by examining the word used to coin it.

The construct of the word tells us that it refers to an action taking place but what is the name of the action?

**Hoist**!

To hoist means to raise something. Hoisting is the process of doing just that 😉

Hoisting can be loosely described as the process of raising variables to the top of their context before the context execution so that every code using (or referring to) that variable will have access to it irrespective of the line in which the code exists in the context. That is why the code written in SNIPPET 2 above could run. This is not something to celebrate until you have sufficient knowledge of what's going on behind the scene.

In JavaScript, the process of hoisting happens during the creation phase of an execution context.

Do you recall from [this article](https://sleekcodes.hashnode.dev/javascript-execution-context-demystified) that during the creation phase of an execution context, all variable and function declarations are put in memory and assigned a value of `undefined`? Let me explain what that "memory" is all about.

The memory that is created during the creation phase of an execution context is called a **variable object**.

> In the Global Execution context, it is the **Global** and/or **Script** object. While in the function execution context, it is commonly referred to as **Activation Object**.

Let's put all this knowledge so far together;  
Using **SNIPPET 2** as a case study, when our program runs, during the creation phase of the global execution context, a memory is created and then the variable `age` is attached to it with an initial value of `undefined`

> Remember that in the creation phase of an execution context, all variable and function declarations are ***taken note of***. We can dare to say they are **hoisted**.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1682649102633/c64e33d2-3b58-4c3d-9198-b659c75960ef.png align="left")

The consequence of this phase is that the program now knows about the variable `age`. Therefore, when the execution phase begins and at **line 1** we attempt to access the value of `age`, we'll get `undefined` because at that point in the execution phase of the program, the variable has not been assigned a value yet. It merely just exists in memory with a default value.

After line 2, if we try to access the variable again, we'll now get its actual value.

So conceptually, during the creation phase of an execution context, all variable and function declarations are raised to the top of the context so that they are accessible from any line during the execution phase of that context.

  
There are several ways to create variables in javascript using the keywords `var`, `let`, and `const`. In the next section of this article, let's examine how these keywords affect the accessibility of the variables they are used to create.


## `Var`, `Let` and `Const`

The `var`, `let`, and `const` keywords are used to declare variables in JavaScript.

There are some persons with the idea that variables are only hoisted when created with the `var` keyword (fair point) but I'd like to state that all keywords support hoisting.  
  
The way I think about it is that the keyword we choose to use when creating variables simply affects how they are accessed in the program.

One major difference between the behaviour of variables created with `var` and those created with `let` or `const`; is that accessing variables created using the `let` or `const` keyword can only be done after the actual line where they were declared physically in the code. That is, you cannot access variables created with the `let` or `const` keyword before they are declared.  
  
*The code in the snippet below will result in an error.*

```javascript
console.log(age); // ReferenceError
let age = 12; 
```

  
Why do I disagree with the idea that variables created using the `let` or `const` keyword isn't hoisted?

This is because, during the creation phase of the context where they exist, they are still put in memory and assigned a value of `undefined`.

That memory is logically located at the top-most of its context making them accessible by child-contexts and child-scopes.  
  
In the global context, a variable created with the `let` or `const` keyword is stored in a type of variable object called **Script**. Those created with the `var` keyword are stored in a variable object called **Global**. While in the function context, all variables are stored in the functions' **Activation Object**.

> NB: Do not get too concerned about the meaning of the term variable or activation object. They are simply conceptual terms to refer to a place in a context where variables created in that context are stored.

  
According to [MDN docs](https://developer.mozilla.org/en-US/docs/Glossary/Hoisting), any of the following behaviours can be regarded as hoisting;

1. Being able to use a variable's value in its scope before the line where it is declared.
    
2. Being able to reference a variable in its scope before the line where it is declared, without throwing a [`ReferenceError`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError), but the value is always [`undefined`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined).
    
3. The declaration of the variable causes behaviour changes in its scope before the line in which it is declared.
    

**All the above-stated behaviours are obtainable at the creation phase of a context.**


### Summary

People mostly associate the term `hosting` to the `var` keyword but the truth is that even variables created using the var keyword are not listed in the [ECMAScript Specification](https://tc39.es/ecma262/#prod-HoistableDeclaration) as hoistable declarations.

Hoisting is just an adopted term to describe what happens during the creation phase of an execution context when variables are put in memory and assigned a default value of `undefined`.

Variables created with the `var` keyword can be referenced from any line even before the line where they are defined, but trying to reference variables created using the `let` or `const` keyword before the line where they are physically declared in the program will result in a `referenceError.`  
  
  
In my next article, I talk about scoping in JavaScript and explain (in detail) the effect of using the `var`, `let` or `const` keyword to create variables in your program. It will help you make more informed decisions on which keyword to use when writing your programs.  
  
*If this article was helpful to you in any way, kindly like and share (you can like up to 10 times). I'll be glad to engage your questions in the comment section* ❤️