📖 JavaScript Closures

Closures are a powerful feature in JavaScript that allow functions to access variables from an enclosing scope, even after that scope has finished executing. This concept is essential for creating functions with private variables, handling asynchronous operations, and building advanced patterns like currying and function factories.

Task

Create a counter function that uses closures to keep track of the count. In this task, you will write a function createCounter that returns an object with two methods: increment and getValue. The increment method should increase the count, and getValue should return the current count.

Coding Examples


// Example function: createCounter
function createCounter() {
    let count = 0;

    return {
        increment: function() {
            count++;
        },
        getValue: function() {
            return count;
        }
    };
}

const counter = createCounter();
counter.increment();
console.log(counter.getValue()); // Output: 1
        

Explanation

function createCounter()
Defines the createCounter function.
let count = 0;
Initializes a local variable count with a value of 0.
return { increment: function() { count++; }, getValue: function() { return count; } }
Returns an object with two methods:
  • increment: Increases the count variable by 1.
  • getValue: Returns the current value of the count variable.
const counter = createCounter();
Calls the createCounter function and stores the returned object in the counter constant.
counter.increment();
Calls the increment method on the counter object, increasing the count.
console.log(counter.getValue());
Logs the current value of the count to the console, which is 1.

Putting It Into Action

To see this code in action, create an HTML file and include the following script. This script will create a counter, increment it, and log the result to the console.


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Closures Example</title>
</head>
<body>
    <script>
        function createCounter() {
            let count = 0;

            return {
                increment: function() {
                    count++;
                },
                getValue: function() {
                    return count;
                }
            };
        }

        const counter = createCounter();
        counter.increment();
        console.log(counter.getValue()); // Output: 1
    </script>
</body>
</html>
        

Challenge

Modify the code to include a decrement method that decreases the count. Ensure that the decrement method cannot decrease the count below zero. Additionally, modify the code to output the results to the browser display using HTML instead of the console.

In order to check your learning, you should attempt to create a solution before revealing the solution provided below.

Solution


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Closures Example with Decrement</title>
</head>
<body>
    <div id="result"></div>
    <script>
        function createCounter() {
            let count = 0;

            return {
                increment: function() {
                    count++;
                },
                decrement: function() {
                    if (count > 0) {
                        count--;
                    }
                },
                getValue: function() {
                    return count;
                }
            };
        }

        function displayResult(result) {
            document.getElementById('result').innerHTML += result + '<br>';
        }

        const counter = createCounter();
        counter.increment();
        counter.increment();
        counter.decrement();
        displayResult(counter.getValue()); // Displays the result on the web page
    </script>
</body>
</html>
                        

References