【问题标题】:How does return work in Javascript without a function being invoked?在没有调用函数的情况下如何在 Javascript 中返回工作?
【发布时间】:2016-07-16 08:57:32
【问题描述】:

我正在学习这个site 并遇到了这个问题和答案:

编写一个 sum 方法,该方法在使用以下任一方法调用时都能正常工作 语法如下。

console.log(sum(2,3));   // Outputs 5  
console.log(sum(2)(3));  // Outputs 5

//回答

function sum(x) {
  if (arguments.length == 2) {
    return arguments[0] + arguments[1];
  } else {
    return function(y) { return x + y; };
  }
}

我理解 if 语句中的代码,但不理解 else 语句中的代码,因为它只是返回一个函数。该函数不是用'()'调用的,所以考虑到console.log(sum(2)(3)); 的第二种情况,我不明白它为什么会返回5。我只能看到它会返回function(3) {return 2 + 3},这应该会引发错误。

【问题讨论】:

  • "...该函数不是用 '()' 调用的..." 它是用 () 调用的。它恰好在第一个() 之后。 sum(2)(3) (2) 调用 sum(3) 调用从 sum(2) 返回的任何内容。

标签: javascript return call


【解决方案1】:
sum(2) = function (y){ return 2 + y }

您正在使用 (3) 调用该函数

【讨论】:

    【解决方案2】:

    您可以将函数存储在变量中。

    基本思路是

    var foo = function(y) {
        return y
    };
    

    所以当我们看

    console.log(sum(2)(3));  
    

    可以写成

    var part1 = sum(2);  //aka part1 = function(y) { return 2 + y; };
    var ans = part1(3);
    console.log(ans);
    

    【讨论】:

    • 早上好,先生,我是 JS 的新手,正在研究 return 如何在幕后工作。能不能想象成这样,比如说我们有类似 var num = function(){return 5} 的代码,是不是当我们在后台返回 5 然后 5 替换函数表达式?
    【解决方案3】:

    else 部分是一个接受 one 参数的anonymous function

    万一sum(2)(3)

    它进入 else 循环,其中x = 2 因为它被称为sum(2),而(3) 是一个没有名字的匿名函数。

    因此,

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

    变成

    return function(3) { return 2 + 3; };
    

    【讨论】:

      【解决方案4】:

      else 语句返回一个函数,其中 x 值封装在第一次调用中

      为了解释它会稍微分解一下

      var fresult = sum(3);
      
      // right now fresult is a function that will add 3 
      // to the variable you call fresult with
      // basically function(y){ return 3 + y; }
      var result = fresult(4);
      
      //result is 7 
      console.log(result);
      

      把它想象成x的值被返回的函数捕获,然后你可以调用它

      这个封装是由在 else 的 return 语句中的匿名函数中创建的闭包创建的

      要了解有关闭包的更多信息,请查看 this MDN Article about them,他们将能够比我更好地解释它。

      他们实际上有一个与你的例子非常相似的例子,他们试图将这个概念解释为类似于工厂:

      function makeAdder(x) {
        return function(y) {
          return x + y;
        };
      }
      
      var add5 = makeAdder(5);
      var add10 = makeAdder(10);
      
      console.log(add5(2));  // 7
      console.log(add10(2)); // 12
      

      文章说:

      在这个例子中,我们定义了一个函数 makeAdder(x),它接受一个 单个参数 x 并返回一个新函数。它返回的函数 接受单个参数 y,并返回 x 和 y 的和。

      本质上,makeAdder 是一个函数工厂——它创建函数 这可以为他们的论点添加一个特定的值。在上面的例子中 我们使用我们的函数工厂来创建两个新函数——一个 给它的参数加 5,一个加 10。

      add5 和 add10 都是闭包。它们共享相同的函数体 定义,但存储不同的环境。在add5的环境中,x 是 5。就 add10 而言,x 是 10。

      因此,如果您习惯于更传统的编程语言,则私有变量的一些用例将与在闭包中捕获变量值相同

      【讨论】:

        【解决方案5】:

        Javascript 与许多语言有点不同。函数可以作为变量传递。在您的情况下,将发生的事情分解为实际发生的步骤时更容易看到。

        首先,由于sum(2) 只有一个参数,我们转到您已经知道的else 块。那里发生的事情是我们正在返回一个函数,用x 代替传递给sum(x) 的变量。所以基本上,返回的是一个返回2 + y 的函数。如果我们想自己写出来,这就是它的样子:

        function(y) {
            return 2 + y;
        }
        

        sum(2)(3) 中的第二组括号基本上是说“调用sum(2) 返回的函数并将参数3 发送给它。

        这里基本上是整个操作的扩展版本:

        function sum(x) {
            if (arguments.length == 2) {
                return arguments[0] + arguments[1];
            } else {
                return function(y) { return x + y; };
            }
        }
        
        var addTwo = sum(2);
        
        console.log(addTwo(3));
        

        简短版本基本上只是跳过为sum(2) 的结果创建单独的变量,而是立即调用新函数。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-12-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-06-23
          • 1970-01-01
          • 2022-01-14
          相关资源
          最近更新 更多