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();
Reference: Practical usage of closures
In practice closures may create elegant designs, allowing customization of various calculations, deferred calls, callbacks, creating encapsulated scope etc.
An example the sort method of arrays which accepts as an argument the sort-condition function:
Mapping functionals as the map method of arrays which maps a new array by the condition of the functional argument:
Often it is convenient to implement search functions with using functional arguments defining almost unlimited conditions for search:
Also, we may note applying functionals as, for example, a forEach method which applies a function to an array of elements:
A function is applied to arguments (to a list of arguments — in apply, and to positioned arguments — in call):
Deferred calls:
Callback functions:
Creation of an encapsulated scope for the purpose of hiding auxiliary objects:
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 variableNow there could be many approaches like:
1) You could use a global variable, and a function to increase the 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:
But, Hey! Every time
updateClickCount()
function is called, the counter is set to 1 again.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 functioncountWrapper()
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.4) Closure to the rescue! (self-invoking function):
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:
There is a section on Practical Closures at the Mozilla Developer Network.
In the given sample the value of the enclosed variable 'counter' is protected and can be altered only using the given functions (increment, decrement). because it is in a closure,
Another common use for closures is to bind
this
in a method to a specific object, allowing it to be called elsewhere (such as as an event handler).Whenever a mousemove event fires,
watcher.follow(evt)
is called.Closures are also an essential part of higher-order functions, allowing the very common pattern of rewriting multiple similar functions as a single higher order function by parameterizing the dissimilar portions. As an abstract example,
becomes
where A and B aren't syntactical units but source code strings (not string literals).
See "Streamlining my javascript with a function" for a concrete example.
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.
Note that the
days
array could simply be stored as a property of thedateUtil
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.