Mastering JavaScript 🧑‍💻: Closures
Tags: javascript, webdev, beginners, programming
Published: 2022-09-10 07:35:51

Hello everyone 👋, I hope you are doing well.

In this post I will explain what closures are using examples as well so that you too can use them to write your code better.

##LEXICAL SCOPE ✍️
Before directly explaining what closures are, it is appropriate to explain the concept of **scope** and **lexical scope**.

The scope of a function refers that area of code where its variables are "visible" and can be used.
If another function is created within one function, another internal scope will then be created, and so on: this is called a _scope chain_.

_Lexical scope_, also called _static scope_, refers to when the location of a function's _**definition**_ determines which variables you have access to.

E.g. :
```
const life = () => {
  const pastEvents = 'past'

  //console.log(actualEvents) this will create an error because that inner variable is not accesible here
  
  const present = () => {    
    const actualEvents = 'present'

    console.log(pastEvents, actualEvents)//ok
    //console.log(futureEvents) same for this one

    const future = () => {
      const futureEvents = 'future'
      
      console.log(pastEvents, actualEvents, futureEvents)//ok      
    }

    future()
  }

  present()
}

life()
/*
Outputs:
  past present
  past present future
*/
```
As you can see, in a nested group of functions the inner functions have access to the variables and other resources of their parent scope.

##CLOSURES 🪆

Let's make some changes to the code from before:

```
const life = () => {
  const pastEvents = 'past'
  
  const present = () => {    
    const actualEvents = 'present'

    console.log(pastEvents, actualEvents)

    const future = () => {
      const futureEvents = 'future'
      
      console.log(pastEvents, actualEvents, futureEvents)  
    }

    return future
  }

  return present
}

const newFunc = () => {
  //different scope
  const newLife = life()
  const future = newLife()

  future() 
}

newFunc()
/*
Outputs:
  past present
  past present future
*/
```

New functions created within the *newFunc* function have access to the variables *pastEvents*, *actualEvents* and *futureEvents* even if they are in another scope.
This is because the *future* and *present* functions are closures: when they are assigned to variables (in our case *newLife* and *future*) they _**close over**_ (from here the term closure) the variables of their lexical scope.

Due to this the closures are *memory efficient* saving code repetitions.
Here another example:

```
const addTo = x => y => x + y //x = outer func; y = inner.
const addToTen = addTo(10)
addToTen(3) // returns 13
```

Another benefit they bring is that of data *encapsulation*:

```
const createCounter = () => {
  let count = 0

  return {
    increment() {
      count++
    },
    decrement() {
      count--
    },
    showCount() {
      console.log(count)
    }
  }
}

const myCounter = createCounter()

for(let i = 0; i < 100; i++)
  myCounter.increment()

myCounter.decrement()

console.log(myCounter.count)//returns undefined
myCounter.showCount()//returns 99
```

In this way, the count variable is private and can be accessed only through proper functions written by the developer.

##CONCLUSIONS

If you have come this far in reading, I thank you. If you liked the post please leave a like and check out my other posts 🙂.