【问题标题】:Functions that return a function返回函数的函数
【发布时间】:2011-11-29 14:27:32
【问题描述】:

我坚持使用“返回函数的函数”这个概念。我指的是 Stoyan Stefanov 的《面向对象的 Javascript》一书。

片段一:

    function a() {
      
        alert('A!');
    
        function b(){
            alert('B!'); 
        }
    
        return b();
    }
    
    var s = a();
    alert('break');
    s();

输出:

A!
B!
break

片段二

function a() {
  
    alert('A!');

    function b(){
        alert('B!'); 
    }

    return b;
}

var s = a();
alert('break');
s();
输出:
A!
break
B!

谁能告诉我上面的sn-ps中返回bb()的区别?

【问题讨论】:

  • 你会注意到第一个 sn-p 在 s(); 上给出了一个错误;
  • 当您只返回 b 时,您会返回调用 s() 时要调用的函数;当你返回 b() 你的调用 b 当你返回它时

标签: javascript


【解决方案1】:

将变量分配给函数(不带括号)会复制对函数的引用。将括号放在函数名的末尾,调用函数,返回函数返回值。

Demo

function a() {
  alert('A');
}
//alerts 'A', returns undefined

function b() {
  alert('B');
  return a;
}
//alerts 'B', returns function a

function c() {
  alert('C');
  return a();
}
//alerts 'C', alerts 'A', returns undefined

alert("Function 'a' returns " + a());
alert("Function 'b' returns " + b());
alert("Function 'c' returns " + c());

在您的示例中,您还在函数中定义函数。如:

function d() {
  function e() {
    alert('E');
  }
  return e;
}
d()();
//alerts 'E'

该函数仍然是可调用的。它仍然存在。这一直在 JavaScript 中使用。函数可以像其他值一样传递just。考虑以下几点:

function counter() {
  var count = 0;
  return function() {
    alert(count++);
  }
}
var count = counter();
count();
count();
count();

函数 count 可以保留在它之外定义的变量。这称为闭包。它在 JavaScript 中也被大量使用。

【讨论】:

  • 片段一:var hero = { name: 'Rafaelo', sayName: function() { return hero.name; }, nayName:hero.sayName } hero.nayName();片段二: var hero = { name: 'Rafaelo', sayName: function() { return hero.name; }, nayName:this.sayName } hero.nayName();第一个 sn-p 给了我正确的输出,而第二个没有。为什么?问候。
  • this 仅表示函数体内的某些内容,否则它是全局的。你对this.sayName 的意思是你想要全局变量sayName,它不存在,它是未定义的,所以是不可调用的。
  • 我被 d()(); 弄糊涂了一开始但后来发现第一个()调用了d,第二个()调用了d的返回值,也就是e。
  • 八年后,这仍然有意义!
【解决方案2】:

返回不带() 的函数名会返回对该函数的引用,可以像使用var s = a() 一样进行分配。 s 现在包含对函数 b() 的引用,调用 s() 在功能上等同于调用 b()

// Return a reference to the function b().
// In your example, the reference is assigned to var s
return b;

在 return 语句中使用 () 调用函数会执行函数,并返回函数返回的任何值。它类似于调用var x = b();,但不是分配b() 的返回值,而是从调用函数a() 返回它。如果函数b() 本身没有返回值,则在b() 完成任何其他工作之后,调用将返回undefined

// Execute function b() and return its value
return b();
// If b() has no return value, this is equivalent to calling b(), followed by
// return undefined;

【讨论】:

  • 在所有答案中,我更喜欢你的答案,因为它很简单。
  • 说得好!这个答案很容易理解。
  • 感谢您验证有关函数是否不返回调用返回未定义值的位。我最近发现了这个问题:即使函数显式返回 null,如果将返回的值分配给变量,它将是未定义的,而不是 null。我想这会在一些代码库中引起很多奇怪的问题,因为 null 和 undefined 与 === 并不完全等价。
  • 这个问题我迟到了几年,但我还是不明白b。所以当s()被调用时,它会调用a()。但由于 b 只是一个引用,它不会通过a() 执行,因此只有a() 执行。函数完成并执行break 但现在因为s()b() 相同,所以它跳回a() 执行它?
  • @Julian 我会尝试进一步澄清。函数a() 永远不会执行b()。它定义/创建函数b(),然后返回函数b()作为它的返回值。最初var s = a(); 调用a() 并将其返回值存储到变量s 中; s 现在拥有函数 b()。 var s 单独包含一个可以执行的函数。 s()() 执行 它拥有的功能(即b()。)所以回到你的问题,没有s() 从不 调用a()s() 调用 b() 因为变量 s 直接引用 function b
【解决方案3】:

return b(); 调用函数 b(),并返回其结果。

return b; 返回对函数 b 的引用,您可以将其存储在变量中以供以后调用。

【讨论】:

    【解决方案4】:

    返回b 是返回一个函数对象。在 Javascript 中,函数只是对象,就像任何其他对象一样。如果您发现这没有帮助,只需将“对象”一词替换为“事物”即可。您可以从函数返回任何对象。您可以返回一个真/假值。一个整数 (1,2,3,4...)。您可以返回一个字符串。您可以返回具有多个属性的复杂对象。你可以返回一个函数。功能只是一个东西。

    在您的情况下,返回 b 返回事物,事物是可调用函数。返回b() 返回可调用函数返回的值。

    考虑这段代码:

    function b() {
       return 42;
    }
    

    使用上面的定义,return b(); 返回值 42。另一方面,return b; 返回一个函数,它本身返回值 42。它们是两个不同的东西。

    【讨论】:

      【解决方案5】:

      当你返回b时,它只是对函数b的引用,但此时并没有被执行。

      当您返回b() 时,您正在执行该函数并返回它的值。

      在您的示例中尝试alerting typeof(s)。片段 b 将为您提供“功能”。 sn-p a 会给你什么?

      【讨论】:

      • 第一个给出'未定义'。这是否意味着 return b() 完全没用?此外,在第二个 sn-p 中,函数 b 是私有的。那么我们如何能够访问函数外部的引用呢?如果可能的话,请给我一个链接,清楚地解释这个概念。谢谢!
      • 我得到了第一个的答案。在函数 b() 中返回 1+2 并且 typeof 显示数字。谢谢。
      • 很高兴你知道了!至于私有函数:在第二个示例中它并不是真正的私有函数,因为您已经返回了它。事实上,它被分配给s。尝试使用return this 而不是return b……然后你就可以使用s.b() ;)
      • 我一定会试一试的。还没有在 Javascript 中达到这个概念。也许几天后。谢谢! :)
      • 函数 a(){ alert("A!");函数 b(){ 警报("B!"); } 返回 b; } var s = a();删除一个; s(); ----end---- Javascript中引用的概念和Java中的一样吗?在这里,我删除了函数 a(),但对 s() 的调用会执行 b()。那么我可以说 s 包含 b 的副本并且不指向 a() 中定义的 b() 吗?
      【解决方案6】:

      把函数想象成一个类型,比如一个 int。您可以在函数中返回整数。 您也可以返回函数,它们是“函数”类型的对象。

      现在语法问题:因为函数返回值,你怎么能返回一个函数而不是返回值呢?

      省略括号!因为没有括号,函数将不会被执行!所以:

      return b;
      

      将返回“函数”(想象一下,如果您返回一个数字),同时:

      return b();
      

      先执行函数然后返回执行得到的值,差别很大!

      【讨论】:

      • 在第二个 sn-p 中,函数 b 是私有的。那么我们如何能够访问函数外部的引用呢?有没有相同的规则?
      • 如果您共享 JavaScript 中的对象(包括函数),它们将不再是私有的。
      • @Cafecorridor:如果私有函数由某物(公共函数)返回或分配给公共变量(嗯,应用程序可访问的变量),您可以轻松地执行 yourvariable( );,否则将返回的函数赋值给一个变量并再次执行 yourvariable();
      【解决方案7】:

      创建一个变量

      var thing1 = undefined;
      

      声明一个函数

      function something1 () {
          return "Hi there, I'm number 1!";
      }
      

      提醒thing1(我们的第一个变量)的

      alert(thing1); // Outputs: "undefined".
      

      现在,如果我们希望 thing1 成为函数 something1引用,这意味着它与我们创建的函数相同,我们会这样做:

      thing1 = something1;
      

      但是,如果我们想要函数的return ,那么我们必须为其分配已执行函数的返回值。使用括号执行函数:

      thing1 = something1(); // Value of thing1: "Hi there, I'm number 1!" 
      

      【讨论】:

        【解决方案8】:

        片段一:

        function a() {
          
            alert('A!');
        
            function b(){
                alert('B!'); 
            }
        
            return b(); //return nothing here as b not defined a return value
        }
        
        var s = a(); //s got nothing assigned as b() and thus a() return nothing.
        alert('break');
        s(); // s equals nothing so nothing will be executed, JavaScript interpreter will complain
        

        语句'b()'表示执行名为'b'的函数,它显示一个带有文本'B!'的对话框

        语句'return b();'表示执行一个名为“b”的函数,然后返回函数“b”返回的内容。但是 'b' 什么也不返回,那么这个语句 'return b()' 也什么都不返回。 如果 b() 返回一个数字,那么 ‘return b()’ 也是一个数字。

        现在's'被分配了'a()'返回的值,它返回'b()',它什么都不是,所以's'什么都不是(在JavaScript中它实际上是一个东西,它是一个'undefined '。所以当你要求 JavaScript 解释 's' 是什么数据类型时,JavaScript 解释器会告诉你 's' 是未定义的。)由于 's' 是未定义的,当你要求 JavaScript 执行此语句时 's( )',你要求 JavaScript 执行一个名为 's' 的函数,但这里的 's' 是一个 'undefined',而不是函数,所以 JavaScript 会抱怨,“嘿,s 不是函数,我不知道”不知道如何处理这个 s”,然后 JavaScript 将显示“Uncaught TypeError: s is not a function”错误消息(在 Firefox 和 Chrome 中测试)


        片段二

        function a() {
          
            alert('A!');
        
            function b(){
                alert('B!'); 
            }
        
            return b; //return pointer to function b here
        }
        
        var s = a();  //s get the value of pointer to b
        alert('break');
        s(); // b() function is executed
        

        现在,函数“a”返回一个指向名为“b”的函数的指针/别名。所以当执行's=a()'时,'s'会得到一个指向b的值,即's'现在是'b'的别名,调用's'等于调用'b'。即's'现在是一个函数。执行's()'表示运行函数'b'(与执行'b()'相同),显示'B!'的对话框将出现(即在函数 'b' 中运行 'alert('B!'); 语句)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-10-31
          • 1970-01-01
          • 1970-01-01
          • 2015-02-13
          • 2021-12-18
          • 2015-10-01
          • 2010-09-15
          相关资源
          最近更新 更多