A Quick Guide To: Closures
Tags: javascript, beginners, codenewbie, webdev
Published: 2022-03-16 18:45:05

Hi programmers! Today we will discussing **closures** in JavaScript. Every heard of them? Whether you have or haven't, I am positive you have used them. 

Without giving too much away, closures are an undeniably necessary concept in order to understand your code and JavaScript as a whole.

Curious to know why? Let's get started. 

________________________________________________

### Learning Goals

1. [What is a Closure?](#closure)
     - [Lexical Scope](#lexical)
     - [Functions as First-Class Citizens](#first)
2. [The Benefits of using Closures](#benefits)
     - [Encapsulation](#encapsulation)
3. [Closure Examples](#examples)
    - [Example 1](#example1)
    - [Example 2](#example2)
4. [Summary + Recap](#recap)

__________________________________________________________

## What is a Closure <a name="closure"></a>

**A closure is the combination of a function and the environment in which it was declared.**

Considered one of the pillars of JavaScript, **closures** allow a function to access variables from an _enclosing_ scope. 

In other words, a closure gives you access to an outer function's scope from an inner function.

When I said that I was _positive_ that you have used closures before, it is because every function in JavaScript forms a closure.

### Lexical Scope <a name="lexical"></a>

You may have noticed I used the term "enclosing" in my description of closure -- let's unravel this by learning what **lexical scope** is. 

Simply, lexical scope is the accessibility of variables dependant on where the function is declared; NOT where the function is invoked (or called). 

For example:

```js

// declare function myFunc()
function myFunc(){
    // declare and assign variable myName
    // myName is in the scope of myFunc()
    const myName = 'Adriana'

    // declare printName()
    function printName(){
      // log the value of variable myName to the console
      console.log(myName)
    }
    return printName()
}


// invoke myFunc()
myFunc()
```

In the above snippet, the function **printName()** is **lexically scoped**. printName() has access to the variable "myName" because we invoke and return printName() within the myFunc()'s scope. 

So, when we invoke myFunc(), the console outputs "Adriana".

JavaScript is cool in the way that we can access a variable declared outside of a function within that function. A lot of languages actually do not allow this behavior. 


### Functions as First-Class Citizens <a name="first"></a>

Want to know what else is cool about functions in JavaScript?

Functions in JavaScript are **First-Class Citizens**. What does this mean? It is a fancy way to say that:
   * Functions can be passed as a parameter to another function. 
   * Functions can be the return value of a function. 

Ultimately, functions are flexible and extremely worth utilizing!

__________________________________________________________


## The Benefits of using Closures <a name="benefits"></a>

Now that we got the idea of what a closure is and how they work -- what are the benefits? 

Because of closures, the JavaScript Engine (V8) ensures that the function has access to all of the variables by keeping all the variables declared outside of the innermost function. 

JavaScript is lexically and statically scoped -- so when JavaScript compiles and looks through your code the first time, the JavaScript Engine (V8) catalogs what needs to be closured even before the code is executed or ran. 

So, the benefits?

* Closures save memory space.
* Closures allow for encapsulation. 
* Closures reduce bugs. 


### Encapsulation <a name="encapsulation"</a>

Encapsulation is the hiding of information so as to not be manipulated by the "outside" world or global scope. 

We use encapsulation because we do **NOT** want to give access to certain functions to users nor allow certain variables (such as something that stores state) to be modified. 

By nesting an inner function within another function, like our example above, we make sure it is not totally accessible. 

Basically, encapsulation ensures that some data is not exposed. Encapsulation promotes the idea of privilege in terms of access to data (or state) or the functions that have access to that data.

__________________________________________________________


## Closure Examples<a name="examples"></a>

Now that we have acknowledged a textbook definition of closures, let's code this out (we are programmers, aren't we?).

### Example 1 <a name="example1"></a>

First, let's declare a function "a" and within "a" declare a variable "cat" set to a string "Charlie":

```js
function a(){
    let cat = 'Charlie'
}
```
Since, we are not returning anything, if we invoked a() we would get undefined. However, our "cat" variable was declared within the function's scope and thus, it is in our memory heap (thanks V8 engine!). 

In order to be a closure, we must **return ** and **declare** a function within another function:

```js
function a(){
    let cat = 'Charlie'
    return function b(){
        let dog = 'Zoie'
    }
}
```
Let's declare AND return function "b" below our cat variable declaration. Within function "b" we declare another variable "dog" and set it to the string "Zoie". Function "b"'s scope now contains access to variable "dog" while also containing access to variable "cat".

So, if we wanted to return the value of variables "cat" and "dog" within the scope of function "b", we could do this:

```js
function a(){
    let cat = 'Charlie'
    return function b(){
        let dog = 'Zoie'
        return `${cat} - ${dog}`
    }
}
```
In your console or sandbox, paste the above code snipped and then invoke/call the functions in this order:

1. a()
2. b()
3. a()()

What did your console output?

* Invoking a() returns function b().
* Invoking b() returns an error "b is not defined".
* Invoking a()() returns our string literal.


### Example 2 <a name="example2"></a>

Let's code out another example:

```js

function outer(){
   let state = 0

}
```

Here I have declared a function "outer" and declared and assigned a variable "state" to the value of 0. 

If we declare and return another function within outer(), can we access "state"?

```js

function outer(){
   let state = 0
   return function inner() {
      return `Our state is currently at: ${state}.`
   }
}
```

Yes! If we paste this code snippet into our sandbox and call outer() and inner(), what is our output?

* Invoking outer() returns the function inner().
* Invoking inner() returns an error "inner is not defined".
* Invoking outer()() returns our string literal with the value of "state."


In both examples, we are able to access the inner function by invoking the outer function. When we double-invoke the outer function, we are able to access the string literals. Why? By enclosing the inner function in the outer function's scope, we can only invoke it internally. So, we must use the outer scope as a bridge to receive the return value of the inner scope. 

So, how were we able to access the variables in the return statement? JavaScript's Engine (V8) reads through the code from outer function to inner function and shoves the variables into the closure (think of a box). The variables are stored for later use and are never removed because V8 sees that the variables are referenced in another function within the outer function's scope. 


__________________________________________________________


## Summary + Recap <a name="recap"></a>

From this article, let's bundle and condense some of the takeaways:

* JavaScript's Engine is **V8**.
* V8 runs and compiles our code. 
* Functions in JavaScript are _lexically scoped_. 
* **Lexical Scope**: the accessibility of variables dependant on where the function is declared; NOT where the function is invoked (or called).
* Functions in JavaScript are **First-Class Citizens**. 
* Variables declared in the global context OR within an enclosing scope are stored in the memory heap. 
* Closures allow a function to access variables from an enclosing scope even after it leaves the scope in which the function is declared.
* Because of closures, the JavaScript Engine ensures that an inner function has access to all of the variables within its enclosing scope. 
* **Encapsulation** = privacy or reduced accessibility of data.



Still not sure about closures? Here are some resources I used to help me further understand:

* [Encapsulation in JavaScript article] (https://medium.com/javascript-scene/encapsulation-in-javascript-26be60e325b4)
* [What is encapsulation in programming?] (https://www.youtube.com/watch?v=sNKKxc4QHqA) 
* [Closures Explained in 100 Seconds](https://www.youtube.com/watch?v=vKJpN5FAeF4)
* [Closures - Beau teaches JavaScript](https://www.youtube.com/watch?v=1JsJx1x35c0)


Thank you for reading along and coding with me :)
Have any questions, comments or suggestions? Leave them below. 

Remember: always code in the way that is best for your learning.