I want to understand about variables, that has been used in returning function.
This is example code
Prototype = {}
Prototype.F =
{
bind: function()
{
var args = arguments, __method = args.shift(), object = args.shift();
return function()
{
return __method.apply(object, args.concat(arguments));
}
}
}
function ObjectA()
{
...
this.addListener = Prototype.F.bind(this.eventSource.addListener,
this.eventSource);
...
}
var a = ObjectA();
a.addListener(this); // assuming 'this' here will point to some window object
As I understand the returning function in bind() is not evaluated until it’s called in the last line. It’s ok to accept. So addListener will hold a function body containing ‘apply’.
But what I don’t understand, when addListener is called, what kind of parameters it is going to have? particularly _method and args will always be uninitialized?
The function that
bindreturns is a closure over the arguments to thebindfunction, and so the__methodargument will be the first argument tobind(in your example call, that will be thethis.eventSource.addListenerfunction).Closures are basically functions that have data bound into them intrinsically. Here’s a simpler example:
The function returned by
makeAlert“closes over” (retains access to) the things in scope within themakeAlertfunction call that created it, including themsgargument. That’s why when we call the function later, it still hasmsgeven though the call tomakeAlerthas long since completed. More about closures here.A key thing to remember about closures is that they retain access to everything that’s in scope where they’re defined, not just the things they they’re obviously using. So for instance:
Even though the event handler has nothing to do with the big data array, it keeps a reference to it, and so keeps that data in memory after the call to
inithas completed. This is because the link that it has is to a behind-the-scenes object (loosely called the “variable object”) that is a container for all of the arguments and local variables in scope where it’s defined. (In this particular case, if you don’t need all that data, just setdatatoundefinedat the end. The event handler will still have a reference todata, but that reference isn’t holding the array anymore, so the array’s memory can be reclaimed.)