JavaScript Scope
Tags: javascript, beginners
Published: 2021-09-03 17:42:35

## What is Scope? 

In short, Scope is context. It's where something is available. In JavaScript, it has to do with where declared variables are accessible, how they are organized and accessed by the JavaScript Engine. 

## The Three Different Types of Scope in JavaScript

### Global Scope 
This is the top of the food chain, so to speak. These are variables that are declared outside of any functions, or block. Variables declared in global scope are accessible everywhere.

```
const favoriteColor = "Blue";
let meal = "Dinner";
var year = 2021;

```

### Function Scope or Local Scope 
Variables are accessible **only** inside of a function. They are not available outside of the function. When you try to call a variable that has been defined inside of a function, outside, you'll get a ReferenceError. This is referred to either as function scope, or local scope. 

```
function pets(){
   const animal = "Kitten";
   const name = "Fluffy";
   console.log(`This is my ${animal}, their name is ${name}`);
}
```

### Block Scope (ES6)
Starting in ES6, variables are only accessible inside of the block, and block scoped. However, this only applies to variables declared with `const` and `let`. It does not apply to those declared with `var`. Functions are also block scoped, but only when using strict mode in your code. 

A block of code, is usually anything created between the curly braces {}. Typically they are if/else statements, loops, and switch statements. If a variable is created using `var` within a block, it's accessible outside of that block, scoped to the current function, or to the global scope. 

This also means that any functions defined with a block of code, are only accessible in that block. 

```
if (true) {
   const month = "September";
   let day = "Friday";
   const year = 2021;

   console.log(month, day, year)
}
```

### Lexical Scope 
Lexical Scope means that any children have access to variables defined in the parent scope. The way variables are organized and accessed is controlled by the placements of functions and blocks within the code. It is lexically bound to the execution context of its parents scope. 

However, it is incredibly important to note, that the way that lexical scope works, is only up. A child can access variables available in its parents scope, but a parent cannot access downwards. Whatever is defined within its children, is not accessible within the parents context. This is called the scope chain, and it is a one-way street essentially, anything on the outside does not have access to what is on the inside.

For example: 

```
function food(){
   const fruit1 = "banana";
   console.log(fruit1);
   function food2() {
     const fruit2 = "apple";
     console.log(fruit1, fruit2);
      function food3() {
         const fruit3 = "orange";
         console.log(fruit1, fruit2, fruit3);
      }
     food3();
   }
  food2();
}
```
When we call `food()` in the console, it will print out: 

```
banana
banana apple 
banana apple orange
```
But if we tried to call `food2()` and `food3()` directly in the console, we get Uncaught ReferenceError, neither function is defined. They are not available within the parents scope. 

This happens because of variable lookup in the scope chain. If one scope needs to find a certain variable, such as `fruit1`, or `fruit2`, within the scope of the `food3()` function, it will lookup to the parents scope to find it. In the case of the variable `fruit2`, looking up one scope to the `food2()` function, `fruit2` is found, and then used. But as `fruit1` has not been found, it looks up another scope, to that of the `food()` function, where it is found, and then used. It will continue to lookup the chain all the way to the global scope, and if during that variable lookup, no variable is found, an error will be presented.