在什么情况下你会使用一个返回另一个函数(Javascript)的函数?

时间:2015-12-18 05:04:43

标签: javascript function

感谢this question我理解函数如何使用两组括号以及函数如何返回另一个在返回后立即触发的函数。

我不明白为什么这很好知道?如何应用它来解决问题?

以下例子:

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

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

工作正常 - 当然。但为什么不这样写呢呢?

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

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

7 个答案:

答案 0 :(得分:2)

让我们采用您提到的相同代码。

    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 = adder3(4)  // 14
    var op1 = adder3(5)  // 15;
希望你明白!!

如果您需要关于关闭的更多信息,请回复我。

答案 1 :(得分:1)

  

您的示例称为闭包

  • 闭包规则和副作用
  1. 即使在外部函数返回后,闭包也可以访问外部函数的变量:

  2. 闭包最重要和最棘手的功能之一是,即使在外部函数返回后,内部函数仍然可以访问外部函数的变量。是的,你读得正确。当JavaScript中的函数执行时,它们使用创建它们时生效的相同范围链。这意味着即使在返回外部函数之后,内部函数仍然可以访问外部函数的变量。因此,您可以稍后在程序中调用内部函数。这个例子说明了:

    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存储对外部函数变量的引用; 它们不存储实际值。当在调用闭包之前外部函数变量的值发生变化时,闭包会变得更有趣。这个强大的功能可以通过创造性的方式加以利用,例如Douglas Crockford首先演示的私有变量示例:
    2. 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
      

      参考网站:http://javascriptissexy.com/understand-javascript-closures-with-ease/

答案 2 :(得分:1)

当您需要依赖某些参数的类似函数时,返回函数的函数很有用。

一个真实的例子:[].sort可以使用自定义比较器函数调用,但定义comparator函数以允许更多自定义是有意义的:

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);
  }
}

然后你可以使用

[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]

答案 3 :(得分:1)

如果我们需要某个具有一定值的特定状态的函数,那么我们可以在另一个函数中使用它并返回它,这样具有特定状态的返回函数可以直接用于不同的场景。 你可以查看关闭的各种例子。 http://javascriptissexy.com/understand-javascript-closures-with-ease/

答案 4 :(得分:0)

如果您知道第一个参数总是相同的话,那么关闭它会很方便,而不是一次又一次地传递它。对于简单的程序,它可能没有意义。但是,对于更频繁处理重复参数的程序,这种技术肯定很方便。

答案 5 :(得分:0)

没有必要立即使用它。您可以使用它来创建一个函数来将它附加到事件或用作异步函数的回调。一个例子可能是这样的:

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

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

这里我附加了一个点击事件,大概是一个按钮。当它被单击时,它将检索输入的值并基于它创建一个函数,并使用新创建的函数调用异步函数作为它的回调。异步函数可能是ajax请求。当异步函数完成工厂创建的函数时,将调用回调函数。它将根据附加事件时指定的参数检查异步函数传递给回调的返回值。

如果我们将dom查找移动到回调函数内部,那么我们就不需要工厂或参数,但是它会使用asynch函数返回时输入中的值,而不是单击该按钮,稍后该值可能已更改。

有时,由于其他原因,您将无法在回调的上下文中获得所需的值。或者它可能只是你想要抽象出一类函数,所以你不必在你使用它的所有地方重新键入一个稍微不同的版本。

答案 6 :(得分:0)

除了关闭之外,你还可以将它用作一次性工作的预处理,考虑你是否必须做一些密集的事情,例如产生一百万件事;

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

(这是概念的一个例子,不是真实安全的一个例子)