The Difference Between `var`, `let` and `const` in Javascript
Tags: javascript, beginners
Published: 2023-07-09 15:10:38

Salam and hello everyone!

Today, I want to write a simple article, describing a fundamental stuff in Javascript, which is the variables. We will look into how we declare the variables, and how it differs from each other.

This article will only focus on the method of variable declaration, and not the data types in Javascript. So, stay tuned!

If you are tired of reading these long words, just scroll to the conclusion, and see the answer.

---

## Javascript Back In Days

Before 2015, the only way for us to declare variable in Javascript is only one - using `var`.

```js
var clan = "Uzumaki";
```

Simple, right? So, after we declare a variable, we can do some modification to the variable in any way possible. Let us consider one situation, where we have a function:

```js
function guardKonoha() {
  var clan = "Uzumaki";
  console.log(clan); // Output: "Uzumaki"

  var clan = "Uchiha";
  console.log(clan); // Output: "Uchiha"

  if (true) {
    var clan = "Haruno";
    console.log(clan); // Output: "Haruno"
  }

  console.log(clan); // Output: "Haruno"
}
```

Great! We can declare a variable using `var`, and we can modify the variable anywhere in the function, even in the `if` section. This is what we called as **functional-scoped** - as long as it is in the same function, it can be modified or redeclared.

Well, suppose that is good, right? Okay, let me bring to you another example.

```js
function attachKonoha() {
  if (true) {
    var clan = "Otsutsuki";
  }

  console.log(clan); // Output: "Otsutsuki"
}
```

Wait, although the variable is declared in `if` statement, we can still console it? The answer is, yes! As I said just now, it is function-scoped, we can declare, and we can redeclare as long as it belongs to the same function.

Well, if that is the case, that means var can be troublesome? It  depends on the usage though, if you see it as desirable output, then it is good to go! However, the variable can be redeclared anywhere in the function, so you might want to be careful with that.

---

## The Introduction Of `let`

In 2015, the ECMAScript has released a new way to declare a variable, called `let`. In the beginning, this might look similar to `var` on first glance, but wait until you see this.

```js
// `var` declaration
var transformations = "Kekkei Genkai"
console.log(transformations); // Output: "Kekkei Genkai"

var transformations = "Kekkei Touta"
console.log(transformations); // Output: "Kekkei Touta"


// `let` declaration
let element = "Raiton ⚡️"
console.log(element); // Output: "Raiton ⚡️"

let element = "Fuuton 💨"
console.log(element); // Output: "Fuuton 💨"
```

In this example, we can see that the behaviour is similar to each other. Let us look deeper into the usage - in the function. Since we already see the `var` redeclaration at the top, let us see the example for `let` instead.

```js

function guardKonoha() {
  let clan = "Uzumaki";
  console.log(clan); // Output: "Uzumaki"

  let clan = "Uchiha";
  console.log(clan); // Output: "Uchiha"

  if (true) {
    let clan = "Haruno";
    console.log(clan); // Output: "Haruno"
  }

  console.log(clan); // Output: "Uchiha"
}
```

So, noticed the difference? Let me show you chunks by chunks.

In the first part, I declare `clan` using `let` as `Uzumaki`, then redeclare it the first time to `Uchiha`. It sounds okay. But then, I entered to `if` block and redeclare the second time to `Haruno`. Well, I logged the value inside `if` just fine, but when I logged after that outside of `if` block, suddenly it is logged as `Uchiha` (?)

![Puzzled](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f61cjp05fhmpfe4cttix.png)

Well, that happens! But what is the reason behind it? `let` is actually **block-scoped**, where it will only affected in a block instance. While we did redeclare the variable in the `if` scope, the value outside remains the same, because it has different blocks!


![The separation of code blocks](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t1k3ttcn6jn1rzzd0gy4.png)

Oh, so we just have to be careful about variable redeclaration, right? Well, let us go into second example, where we try to declare it inside the `if` block. What will, do you think, will happen?

```js
function attachKonoha() {
  if (true) {
    let clan = "Otsutsuki";
  }

  console.log(clan); // Throws error!
```

!!! It throws an error! Since `let` is a block-scoped, means that if we declare it inside `if` block, we cannot get if outside the `if` block? Yes it is! With this, we can prevent variable pollution by not allowing redeclaration of variable outside the scope.

---

## Before We Go Into `const`

Before we go into `const` example, let me give you a new word - mutable. So, what is mutable?

Mutability is an ability for a variable to be reassigned.
Note that every variable can be redeclared, but it doesn't mean that it is mutable.

```js
let clan = "Hyuga";

// This is redeclaration
let clan = "Namikaze";

let clan; // Becomes undefined

// This is reassignment
clan = "Sarutobi";
```

You need to pay attention to the `let` usage.

Redeclaration means that we **replaced the existing memory of the variable to the other value**.

Reassignment means that we **replaced the value of the existing variable, but there is no change in the memory allocation**.

**Mutability only affects the reassignment, while the redeclaration remains intact**.

Both `var` and `let` are mutable, means that the value can be reassigned anytime.

```js
var village = "Konohagakure";
village = "Otogakure";

let eye = "Sharingan";
eye = "Byakugan";
```

Okay, now we are ready to explore `const`!

---

## The Immutability of `const`

The same year, ECMAScript released yet another way to declare a variable using `const`, which should be immutable. Let us look into the usage.

```js
const beast = "Kurama";
console.log(beast); // Output: "Kurama"

const beast = "Gyuki";
console.log(beast); // Output: "Gyuki"

beast = "Chomei"; // Throws error!
```

As you can see, we first declared `beast` as "Kurama", then we redeclared as "Gyuki". We don't see any problem, until I attempt to reassign the `beast` to "Chomei", which throws an error instead! This is what we called as immutable, where we **cannot reassign a `const` variable**.

So, that is the difference between `let` and `const`.

`const` is also a **block-scoped**, means it behaves similar to `let` in term of position of declaration.

```js
function summonBeast() {
  if (true) {
    const beast = "Saiken";
  }
  
  console.log(beast); // Throws error!
}
```

Well, `const` is a short word for "constant", where it should be constant throughout the code.

---

## Misconception of Immutability

Did I say that immutability means that the value won't be able to reassigned, right? Well, let us look further into more example. But this time, we will look into arrays and objects!

```js
const beasts = ["Shukaku", "Matatabi", "Isobu", "Son Goku"];
console.log(beasts[0]); // Output: "Shukaku"

beasts[0] = "Kokuo";
console.log(beasts[0]); // Output: "Kokuo"
```

_Chotto matte kudasai!_ I thought `const` should be immutable right?

Well, you are right! `const` is indeed immutable. However, what happens here is not reassignment, since the value is still an instance of the Array.

While basic type of variable such as `number`, `string` and `boolean` have literal values, it applies a different case for `array` and `objects`. Both `array` and `object` are instances as a value, so once it is declared, we cannot change its instance. For example:

```js
const beasts = ["Shukaku", "Matatabi", "Isobu", "Son Goku"];

beasts[1] = "Kurama"; // This is okay 👍🏽

beasts = ["Kokuo", "Saiken", "Chomei", "Gyuki"];
// Throws error! 👎

const beasts = ["Kokuo", "Saiken", "Chomei", "Gyuki"];
// Variable redeclared, so this is okay 👍🏽
```

So, for both `array` and `object`, you can still change the value inside it, but you cannot change the instance itself.

So, is there a way if I want to make sure any of the value inside `array` or `object` instance become immutable too? The answer is yes, we have! We have to `freeze` it, using `Object` class.

```
const beasts = ["Shukaku", "Matatabi", "Isobu", "Son Goku"];
Object.freeze(beasts);

beasts[0] = "Kurama"; // Nothing happened!
```

`Object.freeze()` will convert `array` or `object` to become `readonly`.

---

## Conclusion

Well, that's it, folks!

TL;DR

`var` is function-scoped and mutable.
`let` is block-scoped and mutable.
`const` is block-scoped and immutable.

So, I hope you get the gist of it, and have fun with Javascript!

Until then, peace be upon ya!