How to use var, let and const in block & function Scopes 
Published: 2022-01-07 08:24:11

 While coding in Javascript you will mostly encounter two main scopes.

## 1. Block Scopes

You will encounter this mostly in if and for loops
```
{
  // Block Scope
}
if (true) {
  // Block Scope
}

for (var i = 1; i <= 10; i++) {
  // Block Scope
}
```

## 2. Function Scopes
You will encounter this in Javascript functions.
```
function sum(a, b) {
  // Function Scope
  var result = a + b;
}

sum(4 + 3);
```

## How do block and function scopes differ ?

The difference is in how variables are defined. We have three ways of defining variables. We can use ``var``, ``let`` or ``const``.

When you use `var` in block scope the variable can be accessed outside the block scope. See the image below , as you will note ``var i`` prints **11** which was the last value of ``i`` in the for loop

![var in block scope](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ovujd8it9qt726dl5ckn.PNG)

However when you use ``let`` and try printing ``var i`` you will get undefined

![let in block scope](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7th6e7oml0g74mbhjpku.PNG)

The major difference is that when you define a variable using ``var`` in the function scope , the variable is only accessible in the function scope.


![var in function scope](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8ieo94tkrolbbqwfaqre.PNG)

```
function sum(a, b) {
  // Function Scope
  var result = a + b;
}

sum(4 + 3);
```

## Best practices

When defining variable in the block scope always use ``let`` or ``const`` this will prevent the variables from leaking from the block scope.

## The ``const`` variable and when should you use it ?

Use the ``const`` keyword  when you dont want the referenced  value of the variable changed. This however doesn't mean that the value is immutable.
Objects and Arrays declared with the  `const` keyword can be mutated however this doesnt apply to ``string`` and ``interger`` types.

```
// Scalar values, This can be mutated
const answer = 42;
const greeting = 'Hello';

// Arrays and Objects, This can be mutated
const numbers = [2, 4, 6];
const person = {
  firstName: 'John',
  lastName: 'Doe',
};
```
Incase you dont want your const arrays and objects mutated . Use ``Object.freeze()``. This can also be used on `let` variables

## Array freezing example:

```
const a = [0];
Object.freeze(a); // The array cannot be modified now.

a[0] = 1; // fails silently

// In strict mode such attempt will throw a TypeError
function fail() {
  "use strict"
  a[0] = 1;
}

fail();

// Attempted to push
a.push(2); // throws a TypeError
```

## Object Freezing
The result of calling Object.freeze(object) only applies to the immediate properties of object itself and will prevent future property addition, removal or value re-assignment operations only on object. If the value of those properties are objects themselves, those objects are not frozen and may be the target of property addition, removal or value re-assignment operations.

```
const employee = {
  name: "Mayank",
  designation: "Developer",
  address: {
    street: "Rohini",
    city: "Delhi"
  }
};

Object.freeze(employee);

employee.name = "Dummy"; // fails silently in non-strict mode
employee.address.city = "Noida"; // attributes of child object can be modified

console.log(employee.address.city) // Output: "Noida"
```
Incase you intend to freeze nested objects i would recommend the use of the [immutable](https://immutable-js.com/#introduction) js library.