VoA
VoA

Reputation: 503

In what scenario would you use a function that returns another function (Javascript)?

Thanks to this question I understand how a function may take two sets of parentheses and how a function may return another function which fires immediately after being returned.

What I do not understand is why this is good to know? How could this be applied to solve a problem?

The example of:

function add(x){    
  return function(y){
    return x + y;
  };
}

add(3)(4) === 7; // true

Works fine - sure. But why not just write it like this instead?

function add(a, b) {
  return a + b;
}

add(3, 4) === 7; // true

Upvotes: 5

Views: 339

Answers (7)

Raja Sekar
Raja Sekar

Reputation: 2130

Lets take the same code which you have mentioned.

    function add(x) {    
      return function(y) {
        return x + y;
      };
    }

    var adder3 = add(3); //Forming adder3
    var op1 = adder3(4)  // 7
    var op1 = adder3(5)  // 9

    // Now adder 10:
    var adder10 = add(10);  //Forming adder3
    var op1 = adder10(4)  // 14
    var op1 = adder10(5)  // 15;

Hope you understand!!

Revert me if you need more info on closure.

Upvotes: 2

Anush Shrestha
Anush Shrestha

Reputation: 318

if we require a function in certain state with certain value then we can use it inside another function and return that, so that the return function with certain state can be directly used in different scenario. you can check out various example on closure. http://javascriptissexy.com/understand-javascript-closures-with-ease/

Upvotes: 1

kaan_atakan
kaan_atakan

Reputation: 4047

there isn't a point to using it immediately. you would use it to create a function to attach it to an event or use as a callback for an asynchronous function. an example might be such:

function factory(param){
   return function(result) {
        if (result==param) dosomething();
   }
}

$('#domobject').click({
     param = $('#domvalue').value;
     asynch_function(factory(param));
});

Here I've attached a click event to presumably a button. When it is clicked it will retrieve the value of an input and create a function based on it and call an asynchronous function with the newly created function as it's callback. The asynchronous function might be an ajax request. When the asynchronous function completes the function that factory created, the callback, will be called. It will check the return value the asynchronous function passed to the callback against the param specified when the event was attached.

If we move the dom lookup to inside the callback function, then we wouldn't need factory or param, but then it would use the value that is in the input at the time when the asynch function has returned, rather than when the button was clicked which is later and the value might have changed.

Sometimes, you won't be able to obtain a value you need in the context of the callback for other reasons. Or it might just be that you want to abstract out a class of functions so you don't have to retype a slightly different version of it in all the places you use it.

Upvotes: 0

Oriol
Oriol

Reputation: 288100

Functions which return functions are useful when you want similar functions which depend on some parameters.

A real life example: [].sort can be called with a custom comparator function, but it can make sense to define a comparator function to allow more customizations:

function comparator(options) { // Function which returns a function
  return function(a, b, tmp) {
    if(options.reverse) tmp = a, a = b, b = tmp;
    if(options.map) a = options.map(a), b = options.map(b);
    if(options.func) return options.func(a, b);
    return a < b ? -1 : (b < a ? 1 : 0);
  }
}

Then you can use

[1,11,10,2].sort(comparator({map: String}));              // [1, 10, 11, 2]
[1,11,10,2].sort(comparator({reverse: true}));            // [11, 10, 2, 1]
[1,11,10,2].sort(comparator({func: Function.prototype})); // [1, 11, 10, 2]

Upvotes: 1

Paul S.
Paul S.

Reputation: 66324

Other than closures you can also use it for pre-processing as a one time job, consider if you had to do something intensive, e.g. generate a million things;

function generateSessionSecrets(lock) {
    var secrets = [], i = 1000000;
    while (i-- > 0) {
        secrets[i] = Math.random();
    }
    return function(key, i) {
        if (key === lock) return secrets[i];
    }
}

var chest = generateSessionSecrets('fizz');
chest('fizz', 0); // e.g. 0.2096199430525303
chest('fizz', 1); // e.g. 0.30329699837602675
// ...
chest('fizz', 0); // still 0.2096199430525303

(This is an example of concept, not an example of real security)

Upvotes: 0

Keval Bhatt
Keval Bhatt

Reputation: 6322

Your example called as closures

  • Closures’ Rules and Side Effects

  1. Closures have access to the outer function’s variable even after the outer function returns:

One of the most important and ticklish features with closures is that the inner function still has access to the outer function’s variables even after the outer function has returned. Yep, you read that correctly. When functions in JavaScript execute, they use the same scope chain that was in effect when they were created. This means that even after the outer function has returned, the inner function still has access to the outer function’s variables. Therefore, you can call the inner function later in your program. This example demonstrates:

function celebrityName(firstName) {
    var nameIntro = "This celebrity is ";
    // this inner function has access to the outer function's variables, including the parameter​
    function lastName(theLastName) {
        return nameIntro + firstName + " " + theLastName;
    }
    return lastName;
}​​
var mjName = celebrityName("Michael"); // At this juncture, the celebrityName outer function has returned.​
​​ // The closure (lastName) is called here after the outer function has returned above​
​ // Yet, the closure still has access to the outer function's variables and parameter​
mjName("Jackson"); // This celebrity is Michael Jackson



  1. Closures store references to the outer function’s variables; they do not store the actual value. 
Closures get more interesting when the value of the outer function’s variable changes before the closure is called. And this powerful feature can be harnessed in creative ways, such as this private variables example first demonstrated by Douglas Crockford:

function celebrityID() {
    var celebrityID = 999;
    // We are returning an object with some inner functions​
    // All the inner functions have access to the outer function's variables​
    return {
        getID: function() {
            // This inner function will return the UPDATED celebrityID variable​
            // It will return the current value of celebrityID, even after the changeTheID function changes it​
            return celebrityID;
        },
        setID: function(theNewID) {
            // This inner function will change the outer function's variable anytime​
            celebrityID = theNewID;
        }
    }​
}​​
var mjID = celebrityID(); // At this juncture, the celebrityID outer function has returned.​
mjID.getID(); // 999​
mjID.setID(567); // Changes the outer function's variable​
mjID.getID(); // 567: It returns the updated celebrityId variable

Reference site : http://javascriptissexy.com/understand-javascript-closures-with-ease/

Upvotes: 1

user405398
user405398

Reputation:

If you know the first param is always going to be the same, then it will convenient to have it closure, instead of passing it again and again. For simple programs, it may not make sense. But, for programs which handles repetitive params more often, this technique definitely comes handy.

Upvotes: 0

Related Questions