Reputation: 10830
What could be the use of Functions returning function in javascript?
For example refer the below code
function a() {
alert('A!');
return function(){
alert('B!');
};
}
To execute both functions we would call a()();
Is there any practical use for such a code construct. Ignore the alert() that is just for example.
Upvotes: 0
Views: 64
Reputation: 382092
The main reason is to use the scope of the constructing function (look for "closure") to build a function using private values. Here's an example :
function makeIdMaker(){
var c = 0;
return function(){
return ++c;
}
}
var zebrasIdMaker = makeIdMaker();
console.log('id first zebra :', zebrasIdMaker()); // 1
console.log('id other zebra :', zebrasIdMaker()); // 2
The c
variable is "private" here : you can only increment it and get a new value. It's also convenient as you can pass it as an event handler (or in any place you pass a function) :
skipZebraIdButton.addEventListener('click', zebrasIdMaker); // click to increment the zebra counter
You can also combine this pattern with the IIFE. Here's a real world example :
// Visibility API helper
// var visible = vis(); // gives the current visibility state
// vis(someFunction); // registers a callback for visibility changes
var vis = (function(){
var stateKey, eventKey, keys = {
hidden: "visibilitychange",
webkitHidden: "webkitvisibilitychange",
mozHidden: "mozvisibilitychange",
msHidden: "msvisibilitychange"
};
for (stateKey in keys) {
if (stateKey in document) {
eventKey = keys[stateKey];
break;
}
}
return function(c) {
if (c) document.addEventListener(eventKey, c);
return !document[stateKey];
}
})();
The IIFE returns the function that I'll use after that. The variables used to build that function don't pollute the external scope. It's also often more readable as the function building is clearly visually scoped.
Upvotes: 4
Reputation: 1951
Yes, there is practical use, for example bind
function, which is used to hardly specify context of execution
Function.prototype.bind = function(){
var fn = this, args = Array.prototype.slice.call(arguments), object = args.shift();
return function(){
return fn.apply(object,
args.concat(Array.prototype.slice.call(arguments)));
};
};
full example:
http://ejohn.org/apps/learn/#86
Upvotes: -1