All About Scopes in JavaScript
Tags: javascript, webdev, tutorial, beginners
Published: 2020-12-28 03:49:59

So you are new to JavaScript and keep hearing the word “scope” but don’t quite understand what its is and why you should care. I am here to come to your rescue. This is a very important fundamental concept to understand so lets walk through a few examples and explain what it is.

**TLDR:** Where variables are accessible 

## Scope
Scope in JavaScript refers to the accessibility of whatever you are referencing is. 

## Lexical Scope
JavaScript has a lexical (aka static) scope. Sounds fancy right? It just means that children have access to the parent scope (this includes variables, functions, etc.) but parents to not have access to the children scopes. 
```javascript
function example() {
  let a = 'test' 
  //This has access to a but not b or c
  function exampleParent() {
    let b = 'hello'
    //This has access to a and b but not c
    function exampleChild(){
      let c = 'Children are special'
      //This has access to a, b, and c
    }
  }
}
```
Lexical for JavaScript means at compile time. This means that JavaScript gets its values at compile time rather than other languages that get it dynamically
```javascript
let animal = 'dog';
function myAnimal() {
  console.log(animal);
}
function quack() {
  let animal = 'duck';
  myAnimal();
}
function meow() {
  let animal = 'cat';
  myAnimal();
}

quack(); // returns dog
meow(); // returns dog
```
If this were run in a dynamic language animal would be different based on the function that was run but since it is lexically scoped (at compile not at runtime) it stays the same. HOWEVER, this is NOT the same as reassigning that variable if you wrote this:
```javascript
let animal = 'dog';

function myAnimal() {
  console.log(animal);
}
function quack() {
  animal = 'duck';
  myAnimal();
}
function meow() {
  animal = 'cat';
  myAnimal();
}

quack(); // returns duck
meow(); // returns cat
```
you would get what you are expecting as this is reassigning your declared variable not trying to declare the same variable again.

JavaScript has 3 kinds of scope along with its overall lexical scope
* Global

* Local (or function)

* Block

Lets briefly dive into what each of them are

## Global Scope
A global scope is anything that is defined outside curly braces. This is usually imports for a file or constants that multiple functions need access to.
```javascript
const testLog = 'test' //this is global scope

function logger(){
  const example = 'not global' //this is not global scope it is local/function scope
  console.log(testlog) //this will work as testLog is globally scoped
}

console.log(example) //this will not work (will error Uncaught ReferenceError: example is not defined) as example is not globally scoped it is locally scoped and is not in the scope of this console log
```
## Local (or function) Scope
A local also known as function scope anything that is defined within the curly braces of a function. This means that if something is defined inside a function only that function will have access to it. lets use the previous example again 
```javascript
const testLog = 'test' //this is global scope

function logger(){
  const example = 'not global' //this is not global scope it is local/function scope
  console.log(testlog) //this will work as testLog is globally scoped
  console.log(example) //this will work as example is locally scoped and we are still within that scope
}

console.log(example) //this will not work (will error Uncaught ReferenceError: example is not defined) as example is not globally scoped it is locally scoped and is not in the scope of this console log
```
## Block Scope
Block Scope is something that was added in ES6 with let and const. This means let and const are available in the curly braces they are defined in. This example will show how that works with showing the difference between var, let, and const, but if you want to learn more about that in detail check out this article. 
```javascript
function blockScopeExample(){
    const IAmCool = true
    if(IAmCool){
        var dog = 'Dakota';    //local/function scoped
        const cat = 'Boo';     //block scoped
        let lizard = 'Lucifer'; //block scoped
        console.log(1, dog); //'1 Dakota'
        console.log(2, cat); //'2 Boo'
        console.log(3, lizard); //'3 Lucifer'
    }
    console.log(4, dog); //'5 Dakota'
    console.log(5, cat); // Uncaught ReferenceError: cat is not defined
    console.log(6, lizard); // Uncaught ReferenceError: lizard is not defined
}
```
Here we can see when we are within the same curly the block scoped variables were available but as soon as we were out of the curly braces they were not. The function scope was available within the function but not outside of it. to put it all together we have this example
```javascript
const global = 'i am global' //global scope
function blockScopeExample(){
    const IAmCool = true
    if(IAmCool){
        var dog = 'Dakota';    //local/function scoped
        const cat = 'Boo';     //block scoped
        let lizard = 'Lucifer'; //block scoped
        console.log(1, dog); //'1 Dakota'
        console.log(2, cat); //'2 Boo'
        console.log(3, lizard); //'3 Lucifer'
        console.log(4, global) //'4 I am global'
    }
    console.log(4, dog); //'5 Dakota'
    console.log(5, cat); // Uncaught ReferenceError: cat is not defined
    console.log(6, lizard); // Uncaught ReferenceError: lizard is not defined
    console.log(7, global); //'7 I am global'
}
    console.log(8, dog); //'Uncaught ReferenceError: dog is not defined'
    console.log(9, cat); // Uncaught ReferenceError: cat is not defined
    console.log(10, lizard); // Uncaught ReferenceError: lizard is not defined
    console.log(11, global); //'11 I am global'
```
Here we can see when we are within the same curly the block scoped variables were available but as soon as we were out of the curly braces they were not. The function scope was available within the function but not outside of it and the globally scoped variable was available everywhere.