如何调用带闭包的Javascript函数?

时间:2017-02-12 16:32:55

标签: javascript closures

版本1

function sayHello2(name){
  var text='Hello'+name;
  var say=function(){
   console.log(text);
    
  };
 return say;
  
}

var say2=sayHello2("David");
say2();   

第2版

function sayHello2(name){
  var text='Hello'+name;
  var say=function(){
   console.log(text);
    
  };
 return say;
  
}

sayHello2("David")();

问题:

  1. 为什么在第一版中,当你使用var say2来调用sayHello2时,你不必添加另一组空括号?
  2. 如果我退出行返回说;,错误信息会说sayHello2不是函数,为什么?
  3. 为什么说say2(); (版本2中的最后一行)?如果我删除该行,则没有任何变化,“HelloDavid”仍将被记录。

1 个答案:

答案 0 :(得分:4)

  1. 在两个代码示例中,都进行了两次函数调用。第一个和第二个之间的区别在于,在第一个样本中,第一个函数调用的结果在第二个函数调用之前存储在say2中。第二个示例立即使用sayHello2()的返回值来调用返回的函数。

  2. 如果没有return语句,则sayHello2()会返回undefined

  3. 此问题的主张是,删除say2();行不会改变行为,这是不正确的。如果您不致电say2(),则不会记录任何内容。

  4. 查看sayHello2()

    function sayHello2(name){
      // Initialize the text that will be logged
      var text='Hello'+name;
    
      // Create the function that will log the message
      var say=function(){
        console.log(text);
      };
    
      // Return the logging function
      return say;
    }
    

    sayHello2()函数返回对调用console.log()的小函数的引用。因为函数是JavaScript中的对象值,所以对函数的引用与任何其他类型的值一样有效,并且可以存储在变量中或在表达式中使用。

    请注意,创建日志记录功能时,使用var初始化完成:

      var say=function(){
        console.log(text);
      };
    

    这与变量say2发生的情况基本相同:

    var say2=sayHello2("David");
    

    除了在这里,在=符号的右侧有一个函数调用而不是函数实例化。

    声明

    say2();
    
    因此,

    调用从sayHello2()的调用返回的少量日志记录函数。

    第二个代码示例执行相同的操作:

    sayHello2("David")();
    

    除了返回的函数引用没有中间存储。相反,引用立即用于进行第二次函数调用。

    在第一个版本中,计算所做的函数调用:

    var say2 = sayHello2("David"); // First function call
    say2(); // Second function call
    

    在第二个版本中:

    // First          // Second
    sayHello2("David")();
    

    在JavaScript中,表单形式为

    something()
    

    总是意味着,“将something解释为对函数的引用,并调用它(不传递任何参数)。”如果something不是对函数的引用,则会出现异常。因此,在版本2中,我们的somethingsayHello2("David")。因为它后面有第二组空括号,这意味着我们告诉JavaScript进行另一个函数调用。