var, let and const.
Tags: webdev, programming, javascript, react
Published: 2023-03-18 16:09:28

There were quite some feature changes in JavaScript ES6, and notable among them is the variable declaration keyword. These keywords have been game-changers in understanding the scope and concepts of declared variables. The **var** keyword is the oldest among the 3 and has been used for several years, but until recently when updates were made to the ES6, the scope problem was solved by the introduction of new keywords: **let** and **const**. Today, we will be discussing all three (3) keywords, their scope and concepts, and when to use them, but first, we will need to talk about **scope** so it helps us understand these keywords when mentioned.

When we talk about **SCOPE**, we talk about the accessibility of a variable. A variable can either be scoped **globally** or **locally**. A **global** variable is one that is declared outside a function, so it can be accessed anywhere in the code, while **local** variables are declared inside a function and can only be accessed within the function where it was created. Now that **scope** has been understood, let’s move on to the main topic of the day.

*** **_VAR_** ***
This has been the oldest declarative keyword in JavaScript. A lot of early JavaScript adopters are so used to it I bet it will be difficult to take it away from their heads, so don’t expect to only encounter **var** in legacy codebases or if you’re working with super senior developers. The **var** keyword has its flaws hence the creation of the other two (2) keywords. Let’s play with some codes to see some of these flaws.

**_SCOPING OF VAR_**:

Scoping of **var** relates mainly to how the variable was declared and how it is being accessed. Var is **function** scoped, so variables are not limited to being accessed in the block where they were declared. In the below code, we will see what it means to declare a **var** variable globally and locally and the scope of each.

```
var games = 'football'

function football() {
    var striker = 'michael'
}
console.log(games);// football
console.log(striker);// Error: striker is not defined
```
The output of this code in the console will be:

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

The output from the **games** variable was **football**, while **striker** gave an error. The reason is that **games** is a **global** variable and so it can be accessed anywhere in the function, while **striker** is a **local** variable and can only be accessed anywhere inside the function.

In the below code, we will try to access the **games** variable inside the function. Let’s see the output.

```
var games = 'football'

function football() {
    var striker = 'michael'
    console.log(striker);
    console.log(games);
}
football()
```
Tadaaaa!!! Like magic, both variables output without errors. And that is because global variables will output anywhere they are called.

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

**_RE-DECLARATION OF VARIABLES_**:
A **var** variable can be re-declared or updated. Let’s see that in code visuals.

```
function football() {
    var striker = 'michael'
    var striker = 'messi'
    striker = 'ronaldo'
    var striker = 'neymar'
    console.log(striker);
}
football()
```
`// The output of this code is neymmar`
From the above code, we declared the variable, re-declared it, updated it and then re-declared it again to arrive at _**neymar**_ as our final output because that was our last declaration.

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

**_IMPORTANT_**!!! This type of code above is the reason why **var** is prone to causing errors. If you have forgotten you had an earlier variable named **_striker_** and it has been declared in some parts of the code with important values, and you mistakenly re-declare it, it could ruin the whole project you’re working on.

**_HOISTING WITH VAR_**:
JavaScript’s default behavior is moving all functions, classes and variables to the top of their scope before the execution of the code, so with var, variables are first initialized as **_undefined_** before the declaration.

```
function football() {
console.log(striker);// undefined
    var striker = 'michael'
    console.log(striker);// michael
}
football()
```

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


*** **_LET_** ***
This is an improved keyword than **_var_**. **_Let_** us take a look at some of the improvements of the let keyword against the **_var_**.

**_BLOCK-SCOPED_**:

It is _block-scoped_ and thereby variables declared inside the block can not be accessed outside it. Let’s take a peep at what that means.

```
function football() {
    let striker = 'michael'
if (striker.length = 6) {
        let forward = 'ronaldinho'
        console.log(forward);// line 7 ronaldinho
        }
    console.log(forward);// line 9 error
}
football()
```
The output of this code is:

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

The output of the variable **_forward_** is _ronaldinho_, because the variable was declared within the block of code, unlike in Line 9 which was called outside the block of code hence returning an error because the variable **_forward_** was not declared in the function named **_football_**.

**_RE-DECLARATION OF VARIABLES_**:

Variables declared with the keyword **_let_** cannot be re-declared as we saw with the **_var_** keyword. Let’s try an example.

```
_function football() {
    let striker = 'michael'
    let striker = 'messi'
    console.log(striker);
}
football()_
```
This code will throw an error because **striker** has been declared and so it can’t be re-declared. The output is this:

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

**_VARIABLES CAN BE UPDATED_**:

Variables can be updated after they have been declared.

```
function football() {
let forward = 'rooney'
    forward = 'mbappe'
    forward = 'kane'
    forward = 'salah'
    console.log(forward);
}
football()
// salah
```
The output of our update variable is thus:

![output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4n51cfhe8ji43eub7ivq.png)

**_GLOBAL VARIABLES CAN BE ACCESSED IN THE BLOCK_**:

```
var games = 'football'
function football() {
    var striker = 'michael'
    console.log(striker);
    console.log(games);
}
football()
```
The output will be the same as that of var.

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

**_HOISTING WITH LET_**:

Like **var**, declarations, classes and functions are hoisted to the top of the code, but with **let**, variables do not initialize as **undefined**. _Let_ does not allow a variable to be called before it is declared. Let’s see how it plays out.

```
function football() {
console.log(striker);
    let striker = 'michael'
    console.log(striker);
}
football()
```
The output of this will be an error.

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

*** **_CONST_** ***

**_const_** variables are constants and their values can not be changed. _const_ shares the same similarities with **let** with maybe very few differences. In addition to all the characteristics of **let**, we can add these few other updates to const.

**_ITS VALUES ARE CONSTANTS AND CANNOT BE UPDATED_**:

Any variable declared with the keyword **_const_**, can not be changed or updated. Unlike **_var_** and **_let_** where their values can be re-declared or updated, **_const_** doesn’t allow for that. Let’s see if we can try that.

```
function football() {
const forward = 'rooney'
    forward = 'mbappe'
    console.log(forward);
}
football()
```
Well, this code threw an error. Let me share it so you can see it too.

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

**_THE PROPERTIES OF AN OBJECT CAN BE MANIPULATED_**:

**_const_** variables are constants and therefore they can not be changed. With objects, the properties can be manipulated but not directly. Let’s see how that can be done.

```
const shopping = {
    grocery: 'sausage',
    fruit: 'apple',
    vegetable: 'carrot'
}

shopping = {
    grocery: 'beef'
}
console.log(shopping.grocery);
```
In the above code, we are trying to change the value of grocery. Can that be done? Well, let’s give it a try. Follow me.

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

Oops…It threw us an **error**. Well, that is expected because that isn’t the right way to change the value of the grocery property. Now, let’s do it the right way. To change the value of grocery, we will do it this way.

```
const shopping = {
    grocery: 'sausage',
    fruit: 'apple',
    vegetable: 'carrot'
}

shopping.grocery = 'beef'
console.log(shopping.grocery);// beef
```
**_HOISTING WITH CONST_**:

Just like _let_, declarations are moved to the top of the code, but they are not initialized as _undefined_.

Thanks for taking the time to go this far in the tutorial. If you have any questions, please feel free to ask me anytime. Also, don’t forget to follow me and like this tutorial.

Thanks and have a great weekend.