At the end of the last post, we looked at a function named createDelegate. The createDelegate function constructed a nested function named shim, and shim created all the magic we needed to invoke an object's method during a button click event. In this post we'll finally put the topic to rest.
First, we have to cover an important topic: scope.
Nesting a function inside a function is essentially nesting a local scope inside a local scope. Note that functions have access to all the variables and arguments in all their ancestor's scopes (as long as the variables aren't hidden by a local variable).
Knowing what we know now, what does the following code display?
The answer is 15. The innermost function has access to both the incoming y parameter of printIt and the global variable x thanks to the scope chain. Now, let's add a twist.
Instead of having the printIt function invoke doAlert, let's return doAlert as an object and execute the function from global scope.
Returning a function object creates a closure, which Wikipedia defines as "a function paired with an environment". Generally speaking, when a function like makePrintIt() exits, all the local variables and arguments are lost. A closure, however, closes over its environment and keeps these local variables and arguments alive. The function captures its execution environment.
Finally, every call into makePrintIt() creates a new closure by pairing a function object with its unique execution environment. That means the following code prints 10, then 15.
With this understanding of closures, I hope you can look at the implementation of Function.createDelegate and understand what is happening!
* The ECMAScript standard only describes how the interpreter has to behave. How scope chains and closures are actually realized is an implementation detail.