Javascript academy #2: Closures
Tags: javascript, node, programming, beginners
Published: 2021-12-03 14:01:59

Welcome to this new academy! In this I will NOT explain you javascript from scratch, the aim of this javascript academy is to explain you some concept in javascript that will help you to understand javascript engine!

Today I will teach you what is a `Closure`?

## Short Definition

A `Closure` is a function that can access to variable outer its own scope.

🤔...

Ok let's take an example!

```javascript
let b = 5

function toto(a) { return a + b }
toto(1) // 6
```

When the JS Engine will pass to the function, it will check for each variable if this variable is available in the current context, here only the variable `a` is available since it's the parameters.

But when it will check the `b` variable, it will check that this variable is not available in the function context! So it will check if this variable is available in the outer context!

This is called a `Closure`!

But the JS Engine need to make some tricks in order to keep the outer variable access in the function!

In fact JS Engine will store the outer variable (`b`) in the memory `heap`! So it keep a reference into this variable and when we will invoke the function, the variable will be available!

In fact this `outer variable` is store in an object name `Lexical environment`.

## What is the `Lexical environment` ?

Lexical environment only exists “theoretically”! It grant all thing that a function need to have in order to be invoked! It's composed in 2 parts:

- Environment Record that will store local variable.

- Reference to the outer variable used in this function.

Now let's look how JS Engine manage variable scope in function

```javascript
const toto = 5 // declared in the global scope

function hello () = {
   let a = 35
   let toto = 45
   console.log(a + toto)
}

hello() // 80
```

Why in the example above when we are calling `console.log(a + toto)` the value of toto is `45` and not `5`?

When we will invoked a function, **JS Engine** will check if the variable is in the **current context** (Environment Record), in this case it will take this value, otherwise it will check if the variable exist in the outer context until reaching the `Global Scope`.


Another example to understand this behavior!

```javascript
const toto = 'toto global | ' // declared in the global scope
const b = 'b global | '

function hello () {
   const a = 'a hello | '
   const toto = 'toto hello | '
   const c = 'c hello | '

   return function hey () {
      const c = 'c hey | '
      console.log(a + toto + b + c)
   }
}

hello()() // a hello | toto hello | b global | c hey |
```

Do you see the logic know?


## The purpose of `Closure`

It use more ressource, so why use closure?

Moreover we can create side effect!

```javascript
let toto = 55

function change() {
   toto = 69
}

change()
console.log(toto) // 69
```

But you can encapsulate data and create some secret & protected variable!

```javascript
function hello() {
   let counter = 0
   return function () {
      counter++
      console.log(counter)
   }
}

const upCounter = hello()
upCounter() // 1
upCounter() // 2
upCounter() // 3
```

Your variable is safe and you can only change it by the function return by `hello`!

Moreover, each instance of `hello()` has its own context!

```javascript
const upCounter1 = hello()
const upCounter2 = hello()

upCounter1() // 1
upCounter1() // 2

upCounter2() // 1
```

## Quizz about Closure

```javascript
const arrFuncs = []

for(var i = 0; i < 5; i++) {
  let toto = function () {
    return i
  }

  arrFuncs.push(toto)
}

console.log(i) // i is 5

arrFuncs.forEach(arrFunc => console.log(arrFunc())) // All logs
```

Why it's logging `5` and not `0, 1, 2, 3, 4` ?!

Let understand this step by step!

```javascript
for(var i = 0; i < 5; i++)
```

equal to

```javascript
var i
for(i = 0; i < 5; i++)
```

Since we are using var, the variable `i` is hoisted to the `global scope`!

So when we are doing

```javascript
  let toto = function () {
    return i
  }
``` 

We are using toto function as `Closure`!

And as we know, closure used `reference` for **outer variable**(var i is an outer variable since it's declares on global scope)

So when we will execute each closure (during the `forEach`) we will get the variable value from the `reference`, and the current value at this point is `5`! 

So this is why we `console log 5` five times!

---

I hope you like this reading!

🎁 You can get my new book `Underrated skills in javascript, make the difference` for FREE if you follow me on [Twitter](https://twitter.com/code__oz) and send message to me 😁 and **SAVE 19$** 💵💵

Or get it [HERE](https://codeoz.gumroad.com/l/RXLYp) 

🇫🇷🥖 For french developper you can check my [YoutubeChannel](https://www.youtube.com/channel/UCC675U1ZUPFASsK9-FjawtA)

🎁 [MY NEWSLETTER](https://www.getrevue.co/profile/code__oz)

☕️ You can [SUPPORT MY WORKS](https://www.buymeacoffee.com/CodeoZ) 🙏

🏃‍♂️ You can follow me on 👇

🕊 Twitter : [https://twitter.com/code__oz](https://twitter.com/code__oz)

👨‍💻 Github: https://github.com/Code-Oz

And you can mark 🔖 this article!