Scope
Tags: javascript
Published: 2021-01-17 00:54:27

Scope refers to where you can access a specific variable or function. From the MDN documentation, “scope is the current context of execution. The context in which values and expressions are "visible" or can be referenced. If a variable or other expression is not "in the current scope," then it is unavailable for use. Scopes can also be layered in a hierarchy, so that child scopes have access to parent scopes, but not vice versa.”

Let's discuss this with a few examples of scopes:

**Function scope**
In the function scope, if we define a function and create a variable and try to access it from outside of that function, what do you think we will get? Lets try it in the console:

```javascript
   function funcScope() {
       let a = 10
       const b = 20
       var c = 5
   console.log(a)
   }

// to execute this function in the console we have to invoke it like so:
funScope()
console.log(a)
console.log(b)
console.log(c)
>10
>Uncaught ReferenceError: a is not defined
>Uncaught ReferenceError: b is not defined
>Uncaught ReferenceError: c is not defined

```
In the above code snippet, first a console.log of `a` returned 10 because it is inside the scope of that function and all other console logs returned `ref error` because they are outside of the scope. It doesn’t have access to those variables that were declared inside the function, which is why you can declare the same variable in other functions.

Now, what about if we declare a variable outside the function and try to access it inside the function and also outside the function? Let's figure it out:

```javascript
let color = ‘red’

function rainbow(){
   let color = ‘orange’
   console.log(color)
}

rainbow()
console.log(color)
> orange
> red

```
Interesting right? In this case variable `color = ‘orange’`, inside the function rainbow can not be accessed outside that function but the variable `color = ‘red’` can be accessed outside the function because it is declared outside the function which means it is in `Global scope`. If you remove the variable from function rainbow, the console.log(color) from the function rainbow will look outside the function to see if there is any variable called `color` declared? In this case, yes so it returns red.

**Block scope**
So what is `block` in JavaScript? A `block` is a set of curly brackets `{ }` that has a chunk of code but it's not the same as a JavaScript object like so:  `{ name: uma, age: 30}`. As `function scope` in `block scope` we can not access variables outside the `block` that is declared inside it. Have a look at an example below:

```javascript
 If (true) {
    let name = ‘Uma’
}
console.log(name)
> uncaught ReferenceError: name is not defined

```
Now here we have one very interesting thing to experiment. Are you guys ready for it? Okay let's do it!

In the above example if we change let to const what happens? Hmm nothing. Same output but how about we change it to var? Lets try it:

```javascript
 if (true) {
    var name = ‘Uma’
}
console.log(name)
> Uma

```
What? 
Yes. You saw it right. It outputs the value of the variable, because `let or const` and `var` have different rules of scope. This is why it’s not recommended to use `var`. `var` might not run any complications in the above example but if you have a scenario where you have the same variable declared outside the block as well then it can definitely cause conflict. Try it yourself. Try adding `var name = ‘Aiden’` on top of above code, then add console.log(name) inside `block` and see what happens? Will it print out both variables or just one?

```javascript
 var name = ‘Aiden’
 if (true) {
    var name = ‘Uma’
    console.log(name)
}
console.log(name)
> Uma
> Uma

```
Yes. It just printed out Uma twice. Now try it with let. You will definitely get both variables like so:
> Uma
> Aiden

**Lexical scope**
Lexical scope, also known as static scope refers to the location where a variable is declared and determines where that variable is available. When we have a nested function it can access variables declared in their outer scope: meaning it’s parent function but not a vice versa. 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/qwft3mmkeyjtj3s7iegc.png)

In the above diagram, there is a nested function. Inside the inner function `inFunc()` there are not any variables declared but when we run that code it will return `Uma` which is declared outside the inner function. If in `outFunc()` also there was not any variable declared it will go above the outer function and search in the global scope. In this case we do have the name variable declare outside `outFunc()` so it will return `Umesh` but if you declare variable inside `inFunc()` function like so:
```javascript
function outFunc(){
    function inFunc() {
         let name = ‘Aiden’
   }
 inFunc()
console.log(name)
}
```
In this case nothing is returned because the outer function doesn’t have access to the inner function. This is called lexical scope. I hope this article gives you little bit of a better idea about scope. 
Thank you for reading.