|Written by Ian Elliot|
|Tuesday, 03 June 2014|
Page 1 of 2
The problem with closure isn't that it is difficult to understand it is difficult to see why you might want to use it.
In fact it really is very simple and very useful.
What is a closure?
Put simply closure means that a function has access to all of the variables declared at the same "level" as it in addition to its local variables – even if any enclosing function has terminated.
Think about this basic definition for a moment.
A function normally has access to everything defined at the same scope as it. For example:
has access to any variables it declares plus all the global variables.
Then myInnerFunction has access to all of its local variables plus any that have been declared in myOuterFunction such as a and of course any global variables.
Everything that should be accessible from with in it is accessible from within it. No shocks or surprises yet.
The part of the definition that is surprising is that it still has access to "everything" after that everything has in principle been destroyed because the myOuterFunction has terminated and all of its variables should no longer exist.
This simple fact means that a Function object can exist well after the code that created it has stopped running and its Function object been garbage collected.
When ever a function, more properly a Function object is created then it captures all of the variables that were defined along with it, and hence are in scope and it has access to these variables as long as it, the Function object, exists.
If this wasn't the case the function would behave differently at different times in the programs execution. This way a function always works in the same way irrespective.
Three Ways To Make A Closure
A closure is formed when a function has a reference to it that persists beyond the natural life of the function.
Exactly how can this come about?
The only way that this can happen is if there is a reference to the function from some other part of the program which is still active. That is, the block of code in which the function is defined terminates and so all of the variables it declared no longer exist, but the function is kept alive because there is a reference to it that lives on in some other part of the program.
Roughly speaking there are three general ways that this can happen but there are lots of minor variations on these ways.
a) Return A Function
One of the most common ways to make a closure is to return a function as the result of another function.
Let's look at the simplest possible example:
If you read through MyOuterFunction you can see it declares a local variable which it sets to 123. It then defines a local function MyInnerFunction which simply displays the value of a. The inner function has access to the variable a because it is local to MyOuterFunction.
So far nothing odd is going on. However, when MyOuterFunction comes to an end it returns a reference to MyInnerFunction.
So if you now write:
you will see closure in action.
The first line stores a reference to MyInnerFunction returned by MyOuterFunction in f. The final line uses the function invocation operator i.e. () to call the function that f is set to. In this case it is MyInnerFunction and this displays an alert box with 123, the value of a in it.
b) Assign A Function To A Global Variable
You can create the closure by simply assigning the function to a global variable if you want to. The only real change to the previous example is that you now have to make use of a function expression to define the function:
This works in exactly the same way as the previous example except that now the inner function is referenced by the global variable f. Recall that in a function that isn't being used as a method this references the Global object.
One small modification that you often see is to invoke the outer function immediately:
c) Incorporate The Function In A Longer Lived Object
Basically this is just a way of getting a longer lived reference to the function. For example you can use a timer:
In this case the timer keeps a reference to the function and this persists after MyOuterFunction has finished so a closure is created. When the function is executed five seconds later it still has access to a.
This is in fact an example of setting a function as an event handler for a DOM object. The setTimeout method belongs to the Window object.
More of this example later.
|Last Updated ( Tuesday, 03 June 2014 )|