Scope and Scope chain in Javascript
Tags: javascript, fundamentals, scope
Published: 2021-05-26 15:46:57

## What is scope?
Scope can be defined as the space in which variables and statements are accessible. It makes it possible to have variables with the same name without colliding with one another and prevents outer scopes from having access to inner scopes.
In Javascript we have three types of scope: ***global scope, function/local scope and block scope***. Let's learn what those are:

### Global scope
- The default scope
- There is only one global scope in the program
- It is the top scope that englobes the entire code
- The declarations inside this space can be accessed anywhere in the code

Take a look at the example below. The function `getAge` is able to reference the `age` that is outside the function but located in the global scope.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b4w4gdw2hr8sifd9roqw.png)

### Local scope or Function scope
- Created by a function invocation
- The declarations inside the function are only accessible there

Let's look at another example. Below we are printing the result of `getAge` function. The `age` constant is located inside the function scope so we are able to return it, but when we try to print it from the global scope we get a reference error. This happens because outer scopes (in this case the global scope) cannot access the inner scope (local scope) created by `getAge`.

![local_scope](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/28aswvbe61q24xp9kvmu.png)
 
### Block scope
- The space between a pair of curly braces *(if block, for block, etc.)*
- Applicable to `let` and `const`
- Declarations are only accessible inside the block

In the example below we are able to print the variable `msgOne` but not constant `msgTwo`. As mentioned before `const` and `let` are block scoped so they are only visible inside the block, in this case inside the `if` statement. On the other hand `var` is function scope so can be accessed within the function.

![block_scope](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1970w21d99qfeb4wku60.png)

## Scope chain

Take a look at the code below. What is printed to the console? The answer is `My name is Joana, I'm from Brazil and I speak brazillian portuguese`. But what makes it possible for the `displayInfo` function to access the constants from outside your scope?
```javascript
const language = 'brazillian portuguese'
const name = 'Ana'

function displayIntroduction() {
  const name = 'Maria'
  const country = 'Brazil'

  function displayInfo() {
    const name = 'Joana'
    console.log(`My name is ${name}, I'm from ${country} and I speak ${language}`)
  }

  return displayInfo()
}

displayIntroduction()
```

Before we dive into how, let me briefly talk about the ***execution context***. This concept won't be covered in this article but it is important to explain what it is in order to make it easier to understand scope chain. So, execution context is an environment in which javascript code is evaluated and executed. When the code first starts running it creates a global execution context and a function execution context is created on each function invocation. The scope chain of this code looks similar to this:

![scope_exec](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zxaetav5cz4gvi87sja5.png)

Each execution context has a ***scope chain***. It consists of the variables and objects referenceable by the execution context. Besides the variables and objects it has a property called `outer` that stores the reference to the parent's scope chain.

When the `displayInfo` function is executed and reaches `name` it searches for it in the local scope chain, finding `Joana` as the value. The same process happens for `country` but it is not in the local scope.

So, how is javascript able to reference it?

When the constant is not found in the local scope javascript reaches to the parent's local memory accessible by the reference stored in `outer`, getting `Brazil` as the value.

Last but not least, the same thing happens to `language` in this case the javascript engine goes all the way up the scope chain reaching the global scope to find the constant, retrieving the value `brazillian portuguese`. It is important to know that the scope chain works only one way, from the inner scope to the outer scopes, making it impossible for the global execution context to have access to `country`, for example.

Also know that since the global execution context is the top context the `outer` points to `null`, so if the variable wasn't there it would be implicitly declared, if not in strict mode, or an error would be returned.

## Conclusion

Scope and scope chain are fundamental topics to understand how the javascript engine process and executes code.

To recap:

- There are three types of scope: global scope, function scope and block scope
- Scopes make possible to have variables with the same name without colliding with each other
- Variables and objects in inner scopes are not accessible from outer scopes
- Scope chain consists of the variables and objects referenceable by the execution context

Thanks for reading :)