If you don´t know anything about the scope of variables, stop reading.
Why are they necessary?
A tipical case is when a function expects a callback function as a parameter, for sample to notify an event, but you want to execute a method of an object (of a specific instance).
That is what you cannot do:
var oFool = {}
oFool.value = 5;
oFool.show = function () { alert(this.value) };
setTimeout(oFool.show, 100);
In this case the function setTimeout is getting as a callback function the code of the function that acts as a method for the object, but out of the scope of that object, that is why the alert will show undefined.
In this case, the solution can be an anonimous:
var oFool = {};
oFool.value = 5;
oFool.show = function () { alert(this.value) };
setTimeout(function () {
oFool.show();
}, 100);
This anonimous function is binded to the same scope that the code in which the function setTimeout is running (that no necessarly is the global scope) and thus it can access to the instance of oFool.
¿When do you need a function that returns a function or when an anonimous function is not the proper solution?
The anonimous function is not the proper solution when the binded scope is changing, for sample inside a loop, because in this case the function will remain binded with the last value of the iterator.
var aLayers = document.getElementsByName("div");
for(k in aLayers) {
var oLayer = aLayers[k];
oLayer.onclick = function () {
alert("div #"+k);
};
}
In this case, all the functions binded to each layer will remain binded to the same scope, therefore the variable k will have the same value for all of them.
A proper solution, useful for more complex cases is:
var aLayers = document.getElementsByName("div");
for(k in aLayers) {
var oLayer = aLayers[k];
oLayer.num = k;
oLayer.onclick = function () {
alert("div #"+this.num);
};
}
Because in this case, the value of the variable k is stored in the scope of each layer and the binded function makes use of this scope (by this).
But we have come here to show the use of a function that returns a function, so let us see a solution that makes use of this technic:
var aLayers = document.getElementsByName("div");
for(k in aLayers) {
var oLayer = aLayers[k];
var fClick = function (p) {
return function () {
alert(p);
};
};
oLayer.onclick = fClick(k);
}
What is going on here is that the function fClick get a parameter p which becomes part of its scope and returns an anonimous function that makes use of this parameter. When fClick(k) is binded to the onclick event, the value of k is binded to the scope of anonimous function that is created at that moment and doesn´t change in the next iteration, in which a new anonimous function will be created with a new scope that will have a different value for k in its variable p.