# Closures

Closures are a fundamental concept in JavaScript, often encountered but not always fully understood. They allow functions to access variables from an enclosing scope, even after that scope has finished execution. Here's a simple explanation and examples to illustrate closures:

### What is a Closure?

A closure is a function that retains access to its lexical scope, even when the function is executed outside that scope. This means that a function defined inside another function will "remember" the environment in which it was created.

### Example 1: Basic Closure

```javascript
function outerFunction() {
    let outerVariable = "I'm outside!";

    function innerFunction() {
        console.log(outerVariable);
    }

    return innerFunction;
}

const myFunction = outerFunction();
myFunction(); // Logs: "I'm outside!"
```

In this example:

* `innerFunction` is defined inside `outerFunction`.
    
* `innerFunction` has access to `outerVariable`, even after `outerFunction` has finished executing.
    
* When we call `myFunction`, it still has access to `outerVariable` due to the closure.
    

### Example 2: Closure with a Counter

```javascript
function createCounter() {
    let count = 0;

    return function() {
        count++;
        console.log(count);
    };
}

const counter = createCounter();
counter(); // Logs: 1
counter(); // Logs: 2
counter(); // Logs: 3
```

In this example:

* `createCounter` returns a function that increments and logs the `count` variable.
    
* Each time we call `counter`, it remembers the value of `count` from its lexical scope.
    

### Practical Use Case: Encapsulation

Closures are often used to create private variables and methods in JavaScript, simulating the concept of encapsulation in object-oriented programming.

```javascript
function createPerson(name) {
    let age = 0;

    return {
        getName: function() {
            return name;
        },
        getAge: function() {
            return age;
        },
        growOlder: function() {
            age++;
        }
    };
}

const person = createPerson("Alice");
console.log(person.getName()); // Logs: "Alice"
console.log(person.getAge());  // Logs: 0
person.growOlder();
console.log(person.getAge());  // Logs: 1
```

In this example:

* The `age` variable is private and can only be accessed through the returned object's methods.
    
* This simulates encapsulation, allowing controlled access to the `age` variable.
    

### Summary

* **Closures** allow functions to retain access to their lexical scope.
    
* They are useful for creating private variables and methods.
    
* They help in managing state in functions that are executed asynchronously or in different contexts.
    

Understanding closures is key to mastering JavaScript, especially when dealing with callbacks, event handlers, and higher-order functions.
