What is a practical use for a closure in JavaScript?

What is a practical use for a closure in JavaScript?

I’m trying my hardest to wrap my head around JavaScript closures.
I get that by returning an inner function, it will have access to any variable defined in its immediate parent.
Where would this be useful to me? Perhaps I haven’t quite got my head around it yet. Most of the examples I have seen online don’t provide any real world code, just vague examples.
Can someone show me a real world use of a closure?
Is this one, for example?
var warnUser = function (msg) {
var calledCount = 0;
return function() {
calledCount++;
alert(msg + ‘\nYou have been warned ‘ + calledCount + ‘ times.’);
};
};

var warnForTamper = warnUser(‘You can not tamper with our HTML.’);
warnForTamper();
warnForTamper();

Solutions/Answers:

Solution 1:

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().

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

Solution 2:

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().


2) 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.

Related:  How to tell if browser/tab is active [duplicate]

3) 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.


4) 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!

More lively example on Closure:

  <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>

Solution 3:

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.

Related:  When is a CDATA section necessary within a script tag?

Solution 4:

Yes, that is a good example of a useful closure. The call to warnUser creates the calledCount variable in its scope and returns an anonymous function which is stored in the warnForTamper variable. Because there is still a closure making use of the calledCount variable, it isn’t deleted upon the function’s exit, so each call to the warnForTamper() will increase the scoped variable and alert the value.

The most common issue I see on StackOverflow is where someone wants to “delay” use of a variable that is increased upon each loop, but because the variable is scoped then each reference to the variable would be after the loop has ended, resulting in the end state of the variable:

for (var i = 0; i < someVar.length; i++)
    window.setTimeout(function () { 
        alert("Value of i was "+i+" when this timer was set" )
    }, 10000);

This would result in every alert showing the same value of i, the value it was increased to when the loop ended. The solution is to create a new closure, a separate scope for the variable. This can be done using an instantly executed anonymous function, which receives the variable and stores its state as an argument:

for (var i = 0; i < someVar.length; i++)
    (function (i) {
        window.setTimeout(function () { 
            alert("Value of i was "+i+" when this timer was set" )
        }, 10000);
    })(i); 

Solution 5:

In the JavaScript (or any ECMAScript) language, in particular, closures are useful in hiding the implementation of functionality while still revealing the interface.

For example, imagine you are writing a class of date utility methods and you want to allow users to lookup weekday names by index but you don’t want them to be able to modify the array of names you use under the hood.

var dateUtil = {
  weekdayShort: (function() {
    var days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
    return function(x) {
      if ((x != parseInt(x)) || (x < 1) || (x > 7)) {
        throw new Error("invalid weekday number");
      }
      return days[x - 1];
    };
  }())
};

Note that the days array could simply be stored as a property of the dateUtil object but then it would be visible to users of the script and they could even change it if they wanted, without even needing your source code. However, since it’s enclosed by the anonymous function which returns the date lookup function it is only accessible by the lookup function so it is now tamper-proof.

Related:  How to sum two fields in AngularJS and show the result in an label?

Solution 6:

I know i am super late in answering this question but it might help anyone still searching for the answer in 2018.

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 put 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 app should have to provide smooth UI experience functionality.

I hope it will help someone.