What is a practical use for a closure in JavaScript?

Suppose, you want to count the number of times user clicked a button on a webpage.

For this, you are triggering a function on onclick event of button to update the count of the variable

<button onclick="updateClickCount()">click me</button>

Now there could be many approaches like:

  1. You could use a global variable, and a function to increase the counter:

     var counter = 0;
    
     function updateClickCount() {
         ++counter;
         // Do something with counter
     }
    

    But, the pitfall is that any script on the page can change the counter, without calling updateClickCount().


  1. Now, you might be thinking of declaring the variable inside the function:

     function updateClickCount() {
         var counter = 0;
         ++counter;
         // Do something with counter
     }
    

    But, hey! Every time updateClickCount() function is called, the counter is set to 1 again.


  1. Thinking about nested functions?

    Nested functions have access to the scope "above" them.

    In this example, the inner function updateClickCount() has access to the counter variable in the parent function countWrapper():

     function countWrapper() {
         var counter = 0;
         function updateClickCount() {
             ++counter;
             // Do something with counter
         }
         updateClickCount();
         return counter;
     }
    

    This could have solved the counter dilemma, if you could reach the updateClickCount() function from the outside and you also need to find a way to execute counter = 0 only once not everytime.


  1. Closure to the rescue! (self-invoking function):

     var updateClickCount = (function(){
         var counter = 0;
    
         return function(){
             ++counter;
             // Do something with counter
         }
     })();
    

    The self-invoking function only runs once. It sets the counter to zero (0), and returns a function expression.

    This way updateClickCount becomes a function. The "wonderful" part is that it can access the counter in the parent scope.

    This is called a JavaScript closure. It makes it possible for a function to have "private" variables.

    The counter is protected by the scope of the anonymous function, and can only be changed using the add function!

A more lively example on closures

<script>
var updateClickCount = (function(){
    var counter = 0;

    return function(){
        ++counter;
        document.getElementById("spnCount").innerHTML = counter;
    }
})();
</script>

<html>
<button onclick="updateClickCount()">click me</button>
<div> you've clicked
    <span id="spnCount"> 0 </span> times!
</div>
</html>

Reference: JavaScript Closures


I've used closures to do things like:

a = (function () {
    var privatefunction = function () {
        alert('hello');
    }

    return {
        publicfunction : function () {
            privatefunction();
        }
    }
})();

As you can see there, a is now an object, with a method publicfunction ( a.publicfunction() ) which calls privatefunction, which only exists inside the closure. You can not call privatefunction directly (i.e. a.privatefunction() ), just publicfunction().

It's a minimal example, but maybe you can see uses to it? We used this to enforce public/private methods.


The example you give is an excellent one. Closures are an abstraction mechanism that allow you to separate concerns very cleanly. Your example is a case of separating instrumentation (counting calls) from semantics (an error-reporting API). Other uses include:

  1. Passing parameterised behaviour into an algorithm (classic higher-order programming):

    function proximity_sort(arr, midpoint) {
        arr.sort(function(a, b) { a -= midpoint; b -= midpoint; return a*a - b*b; });
    }
    
  2. Simulating object oriented programming:

    function counter() {
        var a = 0;
        return {
            inc: function() { ++a; },
            dec: function() { --a; },
            get: function() { return a; },
            reset: function() { a = 0; }
        }
    }
    
  3. Implementing exotic flow control, such as jQuery's Event handling and AJAX APIs.


JavaScript closures can be used to implement throttle and debounce functionality in your application.

Throttling

Throttling puts a limit on as a maximum number of times a function can be called over time. As in "execute this function at most once every 100 milliseconds."

Code:

const throttle = (func, limit) => {
  let isThrottling
  return function() {
    const args = arguments
    const context = this
    if (!isThrottling) {
      func.apply(context, args)
      isThrottling = true
      setTimeout(() => isThrottling = false, limit)
    }
  }
}

Debouncing

Debouncing puts a limit on a function not be called again until a certain amount of time has passed without it being called. As in "execute this function only if 100 milliseconds have passed without it being called."

Code:

const debounce = (func, delay) => {
  let debouncing
  return function() {
    const context = this
    const args = arguments
    clearTimeout(debouncing)
    debouncing = setTimeout(() => func.apply(context, args), delay)
  }
}

As you can see closures helped in implementing two beautiful features which every web application should have to provide smooth UI experience functionality.