JavaScript Basics-Closures
Tags: javascript, tutorial, webdev, beginners
Published: 2021-05-16 09:16:45



In the previous post, we learnt about of [JavaScript Basics- Scopes & Hoisting](https://dev.to/debarshi95/javascript-basics-scopes-hoisting-2lmj).

We saw how variables and functions in **local/function scope and block scope** get restricted within that scope (they cannot be accessed outside the scope). 

In this post, we'll learn how the opposite is true, how we can have access to all variables and functions present in the parent scope, from the child scope.


**Some basics first**

## Lexical Scope in JS:

Lexical scope is the ability of a child function where it has to access all variables present in its parent's scope. The child function is said to be lexically bound to the scope of the parent function. 


Example :
 
```
//Global Scope
var message="Hello JavaScript!"; // Can be accessed anywhere in 
                                    the program

function foo(){  // Function scope
  // Within the scope of foo
   
  var greet = "Hello World!";
  let number = 45;

  function baz(){ // Another Function Scope, lexically bound to 
                     the scope of foo and has access to all 
                     variables present in the scope of foo.


   console.log(greet); // Prints 'Hello World!'

   console.log(number); // Prints '45'
    
  }

baz(); // Called baz within the scope of foo

}
```

In the above example, the child function **baz** declared within the scope of parent function **foo** has access to all the variables declared in **foo's scope.** This was possible as **baz** was ***lexically*** bound to the scope of **foo**.



## Closures

A closure is a feature in JavaScript in which a child function has access to the parent function’s scope **even when the function is executed outside its lexical scope**. 

**According to MDN**:

> A closure is a special kind of object that combines two things: a function, and the environment in which that function was created. The environment consists of any local variables that were in-scope at the time that the closure was created. 

Any function that forms a **closure** has access to three scopes:

* Its own scope — variables defined between its curly brackets

* Parent scope-  variables and function defined in parent 
                 function.
* Global scope - global variables and functions

**Example :**

```
function outer(){
let count=0; // Declared in outer scope

   function increment(){ 
     count++;
     return count; // accessing count from parent scope 
   }
 return increment; // returning the increment method;
}

```

**Here we have two functions:**

* A parent function called **outer** which has a 
  variable **count** assigned to 0, and returns an 
  inner function **increment**.

* A child function **increment** which is **lexically scoped** and 
  forms a **closure**.

* As the child function forms a **closure** it has 
  access to all three scopes - its own scope, parent 
  scope and the global scope.  

We now invoke the parent function **outer** and **store the returned function to variable x**:

```
// Calling in global scope

const x = outer(); // assigned the function increment to 
                          variable x

console.log(x); // Prints the returned function increment

console.log(x()); // invoked the function increment for the first                 
                  // Prints 1;

console.log(x()); // invoked the function increment second time, 
                  // Prints 2;
```

**Here's what's happens now :**

* We invoked the function **outer** which initialized the variable 
  **count** to 0 and assigned the returned function **increment** 
  to variable **x**.

* Logging **x** to console, prints the body of returned function 
  **increment**.

* We now invoke and log **x** for the first time, it increases the 
  value of **count** form parent scope by 1 and returns it.

* Invoking **x** for the second time, increases the previous value 
  of **count** again by 1 and returns it.


In the above example, we saw that even though the child function **increment** was executed outside its parent's scope, it was able to remember the value of the variable **count** and ***increased its previous value*** exactly by 1 one each call. This was possible because the function **increment** had formed a ***closure***.

  
#### Conclusion:

Closures are one of those tricky concepts in JavaScript that are difficult to grasp at first. But once you understand them, you realize that things could not have been any other way.

####  Resources
[MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures)