Scope Matters
Tags: beginners, javascript, tutorial, todayilearned
Published: 2022-07-12 22:53:07

I imagine all of us have encountered this kind of scenario:

We create some variables in the beginning of our program because we know that we are going to need to use them later in the program like so:

```
const num1 = 10;
const num2 = 5;
let num3 = num1 + num2;
```

Great start!

It is time to make the first function for our program. We need to use one of the variables we created as an argument to pass through. We also know that we want to return a specific value and need some extra variables inside the function to help with that. 

```
function myFunction(num1, num2) {
 let product = num1 * num2;
 let ans = product + num3;
 return(ans);
}
```
When we invoke the function and run it through _console.log()_, we get this result:

```
console.log("It returns: " + myFunction(num1, num2));
// It returns: 65
```
Great! Everything works perfectly! Now what if we wanted to take the _ans_ variable and use it again?

```
num3 = ans + num1;
// ReferenceError: ans is not defined
```
This error occurs because the variable ans is only in the scope of the function, not the global scope like _num1_, _num2_, and _num3 _ are. When a variable is only in the scope of a function, it cannot be used anywhere else. In fact there are three different types of scope in JavaScript to keep in mind when programming.

---

## So, What Exactly Is Scope?

To make it simple, scope is a fancy term that describes what code can and not see. In the scenario above, the function could see both inside and outside of its code, but the expression outside of the function what was inside of the function. Let me explain in more detail.

In JavaScript, there are three types of scope: 

- Block scope
- Function scope
- Global scope

**Block Scope**

A block scope contains variables that are declared within curly brackets **{ }**. This is seen within if statements and loops, such as for and while. In short, if you see variables declared within curly brackets, they are in block scope. They _cannot_ be accessed by anything outside of the brackets. It will result in the same error we saw above. We can declare a variable with the same name – one within the block and one outside the block and have them not interfere with one another.

```
if(num1 != num2){
 let fact = "yes";
 console.log(fact);
}
// yes

const fact = "This is fine."
console.log(fact);
// this is fine
```
However, there is an exception. If a variable is declared with the _var_ keyword, it can be accessed from outside the block. This would mean you cannot declare a new variable with that same name.

```
if(num1 != num2){
 var fact = "yes";
 console.log(fact);
}
// yes

const fact = "This is fine."
console.log(fact);
// SyntaxError: Identifier 'fact' has already been declared
``` 
**Function Scope**

A function scope is what we saw in the beginning, so there is not much left to add. The variables declared within the function are considered local variables to the function they are declared in and can only be used within the function. Unlike block scope, this pertains to _all_ keywords, not just let and _const_ keywords.

**Global Scope**

Variables declared within the global scope can be use throughout the entire program since everything has access to it. For example, the three _num_ variables that were previously declared can be used in block scopes or function scopes. 

It is useful when you know what variables you want to have as a global variable. For instance, I can have a _let_ keyword for _num3_ and have it returned by a function. The original value of _num3_ becomes overridden and remains the same until it changes again.

```
const num1 = 5;
const num2 = 10;
let num3 = 15;

console.log(num3)
// 15

function add(num1, num2){
 num3 = num1 * num2;
 return num3;
 // 50
}

console.log(num3);
// 50
```

This also means that if there is a global variable declared as a const, you cannot change the value. If you feel like you are going to be changing the value of a global variable, declare it with the let keyword instead of the _const_ keyword. Better safe than annoyed later!

Now, if you were to declare a new variable inside of a block scope or a function scope, then you would be able to use the same name as the global variable without getting an error.

```
const num1 = 5;
const num3 = 50;

if(num3 === 50){
 const num1 = "I am my own variable"
 console.log(num1)
// I am my own variable
// ignores the global const variable previously declared
}

console.log(num1)
// 5

```
When working with the same variable names within different scopes, remember which value you are working with, or you will become confused! If possible, keep the names related to what you are doing with the variable and only repeat the name in a different scope if it is necessary.

---

## Some Final Advice

If you ever end up in a situation where you see _ReferenceError_ and explains that your variable is not declared, think about what scope it is in within the program. Chances are, you simply declared it in an area with limited scope. 

The best approach to take it this: If you feel like you will be using a variable in multiple places, it is best to declare it as a global scope to ensure it will be seen by the entire program. Most importantly, do not be discouraged! There is always a solution to the problem!

---
Resources:

[W3Schools: JavaScript Scope](https://www.w3schools.com/js/js_scope.asp )

[MDN: Scope](https://developer.mozilla.org/en-US/docs/Glossary/Scope )