Hoisting in JavaScript — let, const, and var
Tags: javascript, react, ruby, rails
Published: 2020-06-17 01:56:19

---
title: Hoisting in JavaScript — let, const, and var
published: true
date: 2020-06-16 05:00:35 UTC
tags: javascript, react, ruby, rubyonrails
canonical_url: 
---

[![](https://cdn-images-1.medium.com/max/2600/0*X3tcSWUGJdSol1ep)](https://medium.com/weekly-webtips/hoisting-in-javascript-let-const-and-var-82f16242827?source=rss-4d9350765dae------2)

# What exactly are `let`, `var`, and `const`?

`let`, `var`, and `const` are different ways to declare a variable in JavaScript. var was the only option in any pre-ES2015 code.let and const were introduced with with ES6.

**Declarations**
JavaScript variables are containers for storing data values. Creating a variable in JavaScript is called “declaring” a variable.

# VAR
Creating new variables in JavaScript is a two-step process. First, we declare the variable:

`var carName;`

After the declaration, the variable **has no value** 
 (technically it has the value of `undefined`). The JavaScript engine sets aside a chunk of memory to store the declared variable. Then, we assign a value to that variable:

`carName = "BMW";`

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/615a8ny6c8z9m6u9fzkn.jpeg)

**Scope**
Scope determines the accessibility (visibility) of variables. In JavaScript there are two types of scope: **local** and **global** scope.

**Global Scope**
Variables declared **Globally** (outside any function) have **Global Scope**.

```
// code here can NOT use carName
function myFunction() {
  var carName = "BMW ";
  // code here CAN use carName
}
// code here can NOT use carName
```
**Block Scope**
Variables declared inside a block {} can be accessed from outside the block. Variables declared with the var keyword cannot have **Block Scope**. Example:
```
{
  var x = 10;
}
// x CAN be used here
```

# LET
ES2015 introduced two important new JavaScript keywords: `let` and `const`.`let` is preferred for variable declaration now.

```
let pi = 3.14159;
/=> undefined
```
**Will throw <mark> an error </mark> if you try to declare the same variable a second time:**

```
let pi = "the ratio between a circle's circumference and diameter";
//=> Uncaught SyntaxError: Identifier 'pi' has already been declared
```

`let` is a signal that the variable may be reassigned. It also signals that the variable will be used only in the block it’s defined in, which is not always the entire containing function. So a variable declared in a block with let is only available for use within that block. Example:

```
let greeting = "say Hi";
   let times = 5;

   if (times > 3) {
        let hello = "say Hello instead";
        console.log(hello);// "say Hello instead"
    }
   console.log(hello) // hello is not defined
```

We see that using `hello` outside of its block (the curly braces where it was defined) returns an error. This is because `let` variables are block-scoped.

However, if the same variable is defined in different scopes, there will be no error:
```
let greeting = "say Hello";
    if (true) {
        let greeting = "say Hello instead";
        console.log(greeting); // "say Hello instead"
    }
    console.log(greeting); // "say Hello"

```

This is because both instances are treated as different variables since they have different scopes. This fact makes `let` a better choice than `var`. When using `let`, we don't have to think if we have used a name for a variable before, as a variable exists only within its scope.

# HOISTING

In JavaScript, a variable can be declared after it has been used, which means that you can use a variable before it has been declared. This behavior is referred to as hoisting.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/4es3jaym2e1bdyv13wqj.jpeg)

Let’s use an example to illustrate how hoisting works. Let’s say that we declare a variable called `students` which contains a list of student names, but we declare that variable after we ask our program to print it:
```
console.log(students);
var students = ['Inna', 'Marco', 'Sam'];
```
Our program returns:
```
undefined
```
But if we tried to declare our variable without the `var` keyword, our program would return the following:
```
Uncaught ReferenceError: students is not defined
```

**This is hoisting in action.** Variables can be declared after they are referenced using the var keyword. In simple terms, our program interpreted our above example like this:
```
var students;
console.log(students);
students =  ['Inna', 'Marco', 'Sam'];
```

>
Unlike variables declared using var, fortunately, in ES6 let and const variables offer much better behavior, *and cannot be hoisted.*


![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/qiw2vv9vk2nnjeu9xqpo.jpeg)
Here’s an example of a program that uses let to declare a variable:
```
let name = "My Name";
function exampleFunction() {
 if (name === "Marko Carson") {
  let name = "Marko Carson";
 }
 console.log(name);
}
exampleFunction();
```

When our code runs, the following result will be returned: `My Name`. `The let name = Marko Carson`; declaration is enclosed within our function, which means that it has local scope. **Because we use the let keyword, our variable is not hoisted.**

>
In summary, variables using var are subject to hoisting, which saves variable declarations in memory. This may result in problems if you define and assign your variables in the wrong order.

`let` and `const` variables are not subject to this feature. However, **an error will be returned** if we try to declare a variable more than once, or reference a variable that has not yet been declared in the relevant scope:

```
let pi = 3.14159;
/=> undefined
let pi = "the ratio between a circle's circumference and diameter";
//=> Uncaught SyntaxError: Identifier 'pi' has already been declared
```

`let` is a signal that **the variable may be reassigned**. It also signals that the variable will be used **only in the block it’s defined in**, which is not always the entire containing function. So a variable declared in a block with `let` is only available for use within that block. Example:
```
let greeting = "say Hi";
   let times = 5;
   if (times > 3) {
        let hello = "say Hello instead";
        console.log(hello);// "say Hello instead"
    }
   console.log(hello) // hello is not defined
```
We see that using `hello` outside of its block (the curly braces where it was defined) returns an error. This is because `let` variables are block scoped.
If the same variable is defined in different scopes, there will be no error:
```
let greeting = "say Hello";
    if (true) {
        let greeting = "say Hello instead";
        console.log(greeting); // "say Hello instead"
    }
    console.log(greeting); // "say Hello"
```

This is because both instances are treated as different variables since they have different scopes. This fact makes `let` a better choice than `var`. When using `let`, we don't have to think if we have used a name for a variable before, as a variable exists only within its scope.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/xez2vs3rpspf0ffyevur.jpeg)

# CONST

Declaring a variable with the `const` reserved word means that not only can it not be redeclared but it also **cannot be reassigned**. This is a good thing for three reasons:

1. When we assign a primitive value (any type of data except an object) to a variable declared with `const`, we know that variable will always contain the same value.

2. When we assign an object to a variable declared with `const`, we know that variable will always point to the same object.

3. When another developer looks at our code and sees a const declaration, they immediately know that variable points to the same object or has the same value every other time it's referenced in the program.
```
const pi = 3.14159;
//=> undefined
 
pi = 2.71828;
//=> Uncaught TypeError: Assignment to constant variable.Conclusion
```
However, because const doesn't allow reassignment after the variable is initialized, we must assign a value right away:

```
const pi;
//=> Uncaught SyntaxError: Missing initializer in const declaration
 
const pi = 3.14159;
//=> undefined

```

Best practice is to always declare variables with `const` and then, if you later realize that the value has to change over the course of your program, circle back to change it to `let`.

# Conclusion


* Use `var`... never.

* Use `let`... when you know the value of a variable will change. For example, a counter variable that starts at 0 and is subsequently incremented to 1, 2, 3, and so on.

* Use `const`... for every other variable.

To connect please check my [Github](https://github.com/ivanadokic), [LinkedIn](https://www.linkedin.com/in/ivana-dokic/) or [Twitter](https://twitter.com/LloydPile).

Thank you for reading!