How variable scoping affects the performance
Tags: html, javascript, beginners, node
Published: 2020-06-26 11:47:23

Hi,

Now we have one interesting topic of **How variable scoping affects the performance.**


Before diving into this topic, first, we need to know what is variable scoping?

###variable scoping

Availability of the variable to a part of the program.
We have three major types of variable scoping
   * Global Scope
   * function Scope
   * Block Scope

###Global Scope

  The variable is available in every part of a program.
Example:
```javascript
   let name = 'alwar';
   function getNamewithAge() {
       const age = 23;
       console.log(name, age);
   }
   function getName() {
       console.log(name);
   }
   getNamewithAge() // alwar, 24
   getName() // alwar
```

###Function Scope

`var` declared variables are available in the inside of the function.

```javascript
    function getName(isUser) {
      if(isUser) {
        var name = 'alwar';
      }
      console.log(name);
    }
    getName(true); // alwar
```

Even though the name is declared inside of the if block, We can able to access the name. Because var variables are function scoped. For most of the cases, this approach is considered a bad practice.

###Block Scope

`let` and `const` declared variables are block-scoped. That is it is only accessible within the block itself.

```javascript
   function getName(isUser) {
      if(isUser) {
        let name = 'alwar';
        console.log(name);
      }
    }
    getName(true); // alwar
```

If we try to access the name outside of the if block, then it will give an error of `name is not defined`

ok, come to the point. Now we know what is the scope?
![wait](https://i.imgur.com/si5QEpN.gif) 

I think We have one thing left to learn. That thing is how variable values will be determined?

For Example 
```javascript
   let name = 'alwar';
   function getNamewithAge() {
       const age = 23;
       console.log(name, age);
   }
   getNamewithAge(); // alwar, 23
```

Here how `name` is logged as `alwar`? For that, we need to know about **scope chain**.

####scope chain:
Actually JS Engine creates the `lexical environment` where variables are stored during the program execution.

for the above code, our lexical environments will be

```javascript
globalLexicalEnvironment = {
  name: 'alwar'
  getNamewithAge: <ref. to getNamewithAge function>
  outer: <null>
}
functionLexicalEnvironment = {
  age: 23
  outer: <globalLexicalEnvironment>
}

```

 While calling the `name` variable, the JS engine will first search into the `functionLexicalEnvironment`. It can’t find it there, so it looks for the variable in the outer scope(`globalLexicalEnvironment`) and finds it there.

###Scope chain and performance
  consider the below two codes
**code-1:**
```javascript
let name = 'alwar';
function getName() {
  console.log(name);
}
getName();
```
**code-2:**
```javascript

function getName() {
  let name = 'alwar';
  console.log(name);
}
getName();
```

These two codes will give the same output. But code-2 has a high performance than compared to code-1.

![Why](https://i.imgur.com/6LndO3C.gif)

Because in code-2, *name* variable is in functionLexicalEnvironment. So no need to go to the outer scope(i.e globalLexicalEnvironment). But in code-1 *name* variable is in globalLexicalEnvironment. So it should go into outer scope(i.e globalLexicalEnvironment) to get that variable. Therefore code-2 saves some significant time to find the variable than compared to code-1. So ***keep the variables within the current scope*** as much as possible to improve the performance.

That's ok. But we have cases like accessing the common objects(ex: document object). 
**Example:**
```javascript
  function updateDOM() {
    document.getElementById('outputPara').innerHTML=  document.getElementById('inputPara').innerHTML
  }
  updateDOM();
```
In the above example, we should go into the outer scope for two times to get the `document` object. To avoid two times  reference of the document object we can cache the document object to improve the performance. That is 

```javascript
  function updateDOM() {
    let docObj = document
    docObj.getElementById('outputPara').innerHTML=  docObj.getElementById('inputPara').innerHTML
  }
  updateDOM();
```

In the above code, the document object can be accessed by one time. This will save time to find the document object.

So we can conclude the two rules 😜
    **1)** keep the variables within the current scope as much as possible
    **2)** If rule 1 is not possible, then cache the outer scoped variables

Reference: https://blog.bitsrc.io/understanding-scope-and-scope-chain-in-javascript-f6637978cf53#:~:text=and%20dynamic%20scoping.-,Scope%20Chain,variable%20or%20reaches%20global%20scope.

Thank you for reading this post😍. I hope you learned something.

Follow me on Twitter at https://twitter.com/alwargak