Tuesday, February 2, 2010

Javascript Closures

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.

What do I need to understand first about Javascript to understand closures?

  1. Javascript uses lexical scoping. Huh? Simply put, local function variables are kept alive even after the function exits. You'll hear this explained a few different ways - "variables are kept alive after the stack frame/pops off/deallocated/ends/completed/{insert geeky word to signify stack frames ending}".
  2. 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...

  1. Line 1 - We create a function called multiplyTemplate with one argument.
  2. Line 2 - The argument is saved to a private variable called multiplier.
  3. 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.
  4. Line 4 - We return the value of multiplier times y. Multiplier is a private method of the outer function.
  5. 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:
    1. multiplyTemplate(5) was fired and a new function context was created.
    2. The argument of 5 was assigned to this function context's private multiplier field.
    3. An anonymous function was returned whose value of x is being RETAINED/KEPT ALIVE even though multiplyTemplate(5) has exited.
  6. 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. 

  1. On main reason is if I need to properly encapsulate data inside an object whether it be transient or a singleton.
  2. 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.


No comments: