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:
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()
.
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.
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 functioncountWrapper()
: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 executecounter = 0
only once not everytime.
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:
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; });}
Simulating object oriented programming:
function counter() { var a = 0; return { inc: function() { ++a; }, dec: function() { --a; }, get: function() { return a; }, reset: function() { a = 0; } }}
Implementing exotic flow control, such as jQuery's Event handling and AJAX APIs.