Differences between var, let and const.
Tags: javascript, programming, tutorial, beginners
Published: 2023-01-31 17:42:16

Let`s talk about one of the ES6 changes more used but not everyone actually know the differences between them.

**Var**
Let´s start with the scope of "var". 
"var" declaration are globally scoped of function/locally scoped. This means that the scope is global when a "var" variable is declared outside a function and we will be able to use it in the whole window.

"var" is function scoped when it is declared within a function. This means that it is available and can be accessed only within that function.

For example

```
var hello = "Hello"

function newHello(){
  var adios = "Bye"
}
```

Here, "hello" is globally scoped because it exists outside a function while "adios" is function scoped. so we can not access the variable "adios" outside of a function. For example:

```
var test = "Hola";

function newHello(){
  var adios = "Bye";
}
console.log(adios); //error: adios is not defined
```

We`ll get an error which is a result of "adios" not being available outside the function.

**We can re-declared and update "var" variables** 

```
var adios = "Bye";
var adios = "hola";
var hola = "Bye";
hola = "hola"
```

Either way we will not get an error and we will able to re-declared the variable

**"var" and hoisting**

Hoisting is a javascript mechanism where variables and function declarations are moved to the top of their scope before code execution. For example:

```
console.log(hola);
var hola = "Bye";
```

It will be interpreted as this:

```
var hola;
console.log(hola); //hola is undefined
hola = "Bye";
```
So "var" variables are hoisted to the top of their scope and initialized with a value of "undefined".

**Main problem of "var"**

```
var adios = "Bye";
var tiempo = 3;

if(tiempo > 2){
  var adios = "Adios";
}
console.log(adios); // "Adios"
```

So, let`s break the code down, since "tiempo > 2" returns true, "adios" is redefined to "Adios". While this is not a problem if you knowingly want "adios" to be redefined, it becomes a problem when you do not realize that a variable "adios" has already been defined before.

If you have used "adios" in other parts of your code, you might be surprised at the output you might get. This will likely cause a lot of bugs in your code. This is why we need "let" and "const".

**"Let"**
"let" is now preferred for variable declaration. It`s no surprise as it comes as an improvement to "var" declarations. It also solves the problem with var that we just covered.

**let is block scoped**
A block is a chunk of a code bounded by {}. A block lives in curly braces. Anything within curly braces is a block.

So a variable declared in a block with "let" is only available for use within that block. Let see an example:

```
let adios = "Bye";
let tiempo = 3;

if(tiempo > 2){
 let hola = "Hello";
 console.log(hola); // "Hello"
}
console.log(hola) //hola is not defined
```

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

**we can update let but not re-declared it.**
Just like "var", a variable declared with "let" can be updated within its scope. Unlike "var", a "let" variable cannot be re-declared within its scope. So while this will work:

```
let adios = "Bye";
adios = "Chau";
```

this will return an error:

```
let adios = "Bye";
let adios = "Chau"; // error: Identifier 'adios' has already been declared
```

However , if the same variable is defined in different scopes, there will be no error:

```
let adios = "Bye";
if(true){
  let adios = "Chau";
  console.log(adios); //"Chau"
}
console.log(adios); //"Bye"
```

So here we see how "let" it the best option between "var" and "let".

**Hoisting of let**
Just like "var", "let" declarations are hoisted to the top. Unlike "var" which initialized as "undefined", the "let" keyword is not initalized. So if you try to use "let" variable before declaration, you will get a "Reference Error".

**Const**
Variables declared with the "const" mantain constant values.
"const" declarations share some similarities with "let" declarations.

**const declarations are block scoped**
Like "let" declarations, "const" declarations can only be accesed within the block they were declared.

**const cannot be updated or re-declared**
This means that the value of a variable declared with "const" remains the same within its scope. It cannot be updated or re-declared. So if we declare a variable with "const", we can neither do this:

```
const adios = "bye";
adios = "chau"; // error: Assignment to constan variable.
```

nor this:

```
const adios = "Bye";
const adios = "Chau"; //error: Identifier 'adios' has already been declared
```

This behavior is somehow different when it comes to objects declared with "const". While a "const" object cannot be updated, the properties of this objects can be updated. Therefore, if we declare a "const" object as this:

```
const adios = {
  message: "Bye",
  tiempo: 3
}
```

While we cannot do this:

```
adios = {
 words: "Hello",
 number: "five"
} // error: Assignment to constant variable.
```

We can do this:

```
adios.message = "Adios";
```

This will update the value of adios.message without returning errors.

**Hoisting of const**
Just like "let", "const" declarations are hoisted to the top but are not initialized.

So to make a little summary about everything, here we go:

- "var" declarations are globally scoped or function scoped while "let" and "const" are block scoped.

- "var" variables can be updated and re-declared within its scope; "let" variables can be updated but not re-declared; "const" variables can neither be updated nor re-declared

- They are all hoisted to the top of their scope. But while "var" variables are initialized with "undefined", "let" and "const" variables are not initialized.

- While "var" and "let" can be declared without being initialized, "const" must be initialized during declaration.

Hope someone found it somehow useful.

Thanks a lot for reading.

Lautaro.