【问题标题】:Difference between "anonymous function" and "function literal" in JavaScript?JavaScript中“匿名函数”和“函数文字”之间的区别?
【发布时间】:2011-05-02 13:03:34
【问题描述】:

Learning JavaScript这本书对匿名函数的定义如下...

函数是对象。因此,您可以通过使用构造函数并将函数分配给变量来创建它们 - 就像 StringArray 或其他类型一样。在以下代码中,使用Function 构造函数创建了一个新函数,函数体和参数作为参数传入:

var sayHi = new Function("toWhom", "alert('Hi' + toWhom);");

这种类型的函数通常被称为匿名函数,因为函数本身没有被直接声明或命名。

这是 JavaScript 中“匿名函数”的正确定义吗?如果不是,什么是匿名函数,匿名函数和函数字面量有什么区别?

【问题讨论】:

  • 这不是最常被称为“匿名”的函数类型。那将是一个没有名字的FunctionExpression,例如:var fn = function(){..} vs var fn = function fn(){...}
  • 我不认为这是一本好书,但我只能依靠这一个sn-p来判断。

标签: javascript terminology


【解决方案1】:

函数表达式和函数声明

由于您对函数感兴趣,所以这里有一些重要的知识。

var abc = function() { ... } 被称为函数表达式。该变量将在执行时分配给该匿名函数,尽管其变量声明将被提升到当前执行上下文(作用域)的顶部。

然而,一个函数表达式也可以被命名,这样它就可以在它的主体中被调用来使其递归。请记住IE has some issues。当你给它一个名字时,它绝对是不是一个匿名函数。

function abc() { ... } 等函数称为函数声明。它的定义被提升到其范围的顶部。它的名称在它及其父级范围内可用。

Further Reading.


你的例子

它是一个匿名函数,但分配给变量sayHi

正如Šime Vidas 所提到的,使用new 运算符实例化一个新的Function 对象,并将参数和函数体作为字符串传入。生成的对象分配给sayHi

在现实世界中使用这种方法创建函数的情况很少见(尽管它可能只是为了帮助表明函数是对象)。我还相信将其参数列表和函数体作为字符串传递将调用 eval() 类型的函数,当有更好的构造可用时,这很少是好的。

另外,使用Function do not form a closure 创建的函数。

如果出于某种原因我需要创建一个 Function 及其参数和/或正文只能作为字符串提供给我,我只会使用此方法。

在现实世界中,你会这样做......

var sayHi = function(toWhom) {
   alert('Hi' + toWhom);
};

另请参阅FelixŠime 的 cmets 进行良好讨论和进一步澄清。

【讨论】:

  • 因此匿名函数和函数字面量是同一个意思吗?
  • @Richard 我认为这是主观的。
  • @Richard:我没有经常听到function literal。重要的是函数表达式函数声明之间的区别。如果我们将函数表达式视为函数文字,那么不,它是不一样的。正如@alex 已经解释的那样,有 命名函数表达式 不再是匿名的,函数有一个名称。但它们仍然是函数表达式(= 函数字面量)。
  • @alex "这被称为函数表达式。" - 不,它是使用 Function 构造函数创建的函数对象。函数表达式是这样的:function Identifieropt ( FormalParameterListopt ) { FunctionBody }
  • @RichardJPLeGuen:我会说函数声明会在定义函数的范围内添加一个新符号。该符号与函数名同名。考虑另一个例子:function a(){}; var b = a;。虽然函数被分配给b,但它的名字仍然是a。我建议你看一下函数的name property(也适用于 Chrome),看看哪个语句生成了什么样的函数。
【解决方案2】:

我认为匿名函数的更广泛和更被接受的定义是创建时没有名称的函数。

【讨论】:

    【解决方案3】:

    匿名函数只是一个没有名字的函数。

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

    上面的代码将毫无用处,因为它没有您可以调用它的名称。所以它们通常被分配给一个变量。

    var func = function(a, b){
      return a + b;
    }
    

    这很有帮助,因为您可以将匿名函数传递给另一个函数或方法,而无需事先创建函数,如下所示。

    function bob(a){
      alert(a());
    }
    
    bob(function(){
      return 10*10;
    })
    

    【讨论】:

    • @Sean_Kinsey 没错,这就是为什么我说它没用,并继续展示它如何与其他代码一起使用。
    【解决方案4】:

    这个:

    new Function("toWhom", "alert('Hi' + toWhom);")
    

    还有这个:

    function(toWhom) { alert('Hi' + toWhom); }
    

    是产生相同结果的两个表达式 - 它们返回一个新的匿名函数对象。

    第二个表达式(并且只有第二个表达式)称为函数表达式。您也可以将其称为函数字面量(尽管我们可以争辩说函数声明也是函数字面量)。

    【讨论】:

      【解决方案5】:
      function foo(){
          alert("i'm foo, nice to meet you!");
      }
      var bar = function(){
          alert("I am an anonymous function assigned to the variable \"bar\"");
      }
      

      【讨论】:

      • 那么匿名函数是函数字面量的同义词吗?
      • @Richard - 没有“函数文字”之类的东西,除非您在 javascript 中引用函数的正式语法。替代方法是使用 Function 构造函数创建的函数。在 js 中你有三种创建函数的方法,使用 FunctionDeclaration's(名称必须)、FunctionExpressions(名称可选)和 FunctionConstructor(名称可选)。后两者具有可选名称,因为它们可以在表达式中使用,因此被称为操作数。
      猜你喜欢
      • 2013-03-29
      • 2019-09-03
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      • 2011-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多