Scopes in Javascript
Tags: javascript, beginners, webdev, programming
Published: 2021-04-26 15:11:06

Scope in Javascript basically means the area of code where a particular variable or function is available.
There are 2 types of scopes in Javascript - 
1. Function Scope
2. Block scope

This article will cover both of them in detail and we will try to understand what they mean. If you have prior experience in other languages like Java, Python, etc., you might find it a bit weird, but I hope that everyone will have a clear understanding of how scopes work in Javascript by the end of this article.

P.S. - You can check out the TL;DR at the bottom of the article

# Function Scope

Let us begin by guessing the output of this simple example.
```
function foo() {
    if(true) {
        var x = 10;
    }
    console.log(x);
}
foo(); // ??
```
If you answered undefined or some error, then you'd be surprised to see that this prints `10` to the console.

Let's dive deeper to understand what is going on under the hood.

## Understanding the example

When the function `foo` is called, javascript creates a new execution context for `foo` and puts it on top of the call stack.

`Execution context` contains all the variables and functions that are defined inside the function scope. So before the execution of the function starts, it gets all the variables defined in the `foo` function(i.e. x) and puts a value of `undefined` to them.

>Another point to note here is that what we see is 
`var x = 10;`, whereas the JS engine breaks it into two lines
`var x;` and `x=10` i.e the variable declaration and function assignment. 
This is broken up and put into tp be put into the Abstract Syntax Tree which is outside the scope of this article.

Now as the function continues its execution, it assigns the value 10 to x and then prints it out to the console.

What we encountered here is called `Hoisting`, you may have also read about hoisting where people say that while compilation the declarations are moved to the top whereas, in reality, the execution scope just parses the context and keeps the value of all defined variables as `undefined` before execution.

In function scope, all the variables declared inside the function can be used at any place inside the function even before they are declared although it is considered a bad practice to use any variable or function before declaring them.

# Block Scope
Let's look at a slightly modified version of our last example.
```
function foo() {
    if(true) {
        let x = 10;
    }
    console.log(x); // ??
}

foo();
```
This time we got a `Reference Error` saying `x is not defined`. This should have been the expected behavior all along.

Originally JS did not have `block scope` and it was introduced to Javascript in ES6.

To understand block scope first, we need to understand what a block is.

`{ ... }` -> This is what a block is. A pair of curly braces and everything inside them is a block. Maybe now you understand why we got a reference error while trying to use x in the second example.

But unlike function scope, you are not allowed to use the variables before declaring them. (Because `let` and `const` are not hoisted)

Note - Both function and block scope have a reference to their lexical environment which is used when a certain variable is not found in the same environment.

# TL;DR
`Function scope` is when variables defined in an execution context are available throughout the execution context.

`Block scope` is when variables defined in a scope are available only in the current scope and not outside the scope even though it is still in the same execution context.

# Conclusion
In this article, we discussed the two different kinds of scopes in Javascript and discussed them in detail.

You can learn more about Scopes in this famous book [Scopes and Closures](https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/scope%20&%20closures/README.md#you-dont-know-js-scope--closures) by Kyle Simpson.