What is a closure?
If a function is created in such a way that it will retain it's local variable scope even after the function exits - then its a closure.
- By default, inner functions have access to variables within their outer functions. It does not matter whether its 1 or 10 levels up. This is absolutely paramount in understanding closures.
How do you create a closure?
Any time you create a function within a function and the inner function refers to an outer function's private variable, you've created a closure. Simple as that, don't over complicate it.
A Simple Closure
In this example, here is what's going on...
- Line 1 - We create a function called multiplyTemplate with one argument.
- Line 2 - The argument is saved to a private variable called multiplier.
- Line 3 - We declared an inner function. Something should have clicked here. Remember what I mentioned about inner functions having access to parent function's variables scope. multiplyTemplate is now a closure. Why? Because it is using its PARENT function's private variable multiplier. What's going on here to the end of this inner function on line 5 is absolutely critical to understanding closures.
- Line 4 - We return the value of multiplier times y. Multiplier is a private method of the outer function.
- Line 8 - we create a new variable that executes multiplyTemplate(5). Remember the return of is a multiplyTemplate function, not a primitive int value. It's on this line where the rubber meets the road. Here is what just happened:
- multiplyTemplate(5) was fired and a new function context was created.
- The argument of 5 was assigned to this function context's private multiplier field.
- An anonymous function was returned whose value of x is being RETAINED/KEPT ALIVE even though multiplyTemplate(5) has exited.
- Line 10 - multiplyBy5(10) is executed using the function context declared on Line 8. The argument 10 is actually the y argument on line 3 which uses x to multiply to itself. The multiplier x is still 5 through closure and the value that returns is 50.
Why use a closure?
I'm sure there are a handful of reasons where you would want to use a closure, however in my experience I've only used them for a couple reasons.
- On main reason is if I need to properly encapsulate data inside an object whether it be transient or a singleton.
- Attaching event handlers to a DOM object via anonymous methods+closure inside of a for loop.
That's the skinny. There are many many many resources out there that explain closures in less-than-understandable format but hopefully this helps demystify it a bit.