Javascript 匿名和命名函数

Javascript 匿名和命名函数,javascript,function,anonymous-function,Javascript,Function,Anonymous Function,调试时我发现这类函数: var f = function() {}; 在firebug或webkits开发控制台的堆栈跟踪中显示为匿名,这是理所当然的 我还看到人们将这些定义为: var someName = function otherName(){}; 这很奇怪。请注意,这里您不能从任何地方调用otherName(),而是调用otherName本身的主体。在其他任何地方,您都必须使用someName() 我的问题是: 命名一个不同于存储它的变量的函数有什么问题吗 除了只在堆栈跟踪中显示

调试时我发现这类函数:

var f = function() {};
在firebug或webkits开发控制台的堆栈跟踪中显示为匿名,这是理所当然的

我还看到人们将这些定义为:

var someName = function otherName(){};
这很奇怪。请注意,这里您不能从任何地方调用
otherName()
,而是调用
otherName
本身的主体。在其他任何地方,您都必须使用
someName()

我的问题是:

  • 命名一个不同于存储它的变量的函数有什么问题吗

  • 除了只在堆栈跟踪中显示名称外,
    var a=function a(){}
    还有什么区别吗

  • 关于此主题的任何其他提示/建议:)


    • 不太可能。使用
      var a=function b(){}
      时,命名函数不会被提升,其原型也不会被有意义地修改。以以下代码为例:

      function foo() {
      }
      foo.prototype.bar = "hi";
      
      var a = new foo();         // this inherits from function foo() above
      var b = function foo() {}; // this has nothing to do with the above
      
      console.log(a.bar); // returns "hi" due to inheritance
      console.log(b.bar); // returns undefined; its prototype is a new named
                          // function
      
      var c = function() {};
      var d = function d() {};
      
      console.log(c.name); // returns ""
      console.log(d.name); // returns "d"
      

      在AICT中,主要有用的方法是使
      名称易于访问(主要用于
      var a=function a(){}
      形式),这在某些边缘情况下可能很有用,我认为主要是在错误处理方面。

      将名为f的函数分配给名为a的变量没有问题

      关于函数的一个很好的参考是。特别令人感兴趣的是题为“函数构造函数vs.函数声明vs.函数表达式”的部分,该部分详细讨论了函数名与函数所赋变量之间的区别。(您可能已经看到了这一点。)

      我猜是调试器打印以下内容的原因

      var a = function a() {}
      
      函数的名称在函数值本身序列化时出现。调试器正在为您提供它所拥有的所有信息

      请注意,在这里,除了otherName本身的主体之外,您不能从任何地方调用otherName()

      不在IE中(包括IE8)


      有关更多命名函数bug,请参阅非常好的文章。

      关于答案的最后一部分,让
      名称可访问是什么意思?。如果函数未命名,它如何不可访问?
      var a=new foo()
      varb=函数foo(){}是两种不同类型的语句。比较它们是没有意义的。@Pablo请看我的编辑。我是说
      var foo=function(){}
      名称是
      ,但是
      var bar=function bar(){}
      名称是
      “bar”
      。我相信你也注意到了这一点。我不认为这很有用,只是说如果你想知道函数的名称,这就是你得到它的方式。@Felix是的,也许我应该更清楚,但这就是我想要指出的;您对
      函数foo(){}
      的原型所做的一切都与
      var bar=function foo(){}
      无关。由于继承在这里变得相当笨拙,主要的好处是有一个
      名称
      ,这在大多数情况下是不必要的。@Bryan:我认为最好是
      console.log(b.prototype.bar)在这种情况下。当然,
      b.bar
      不能产生与
      a.bar
      相同的结果
      a
      是从原型继承的对象,
      b
      是函数。最好说明
      b
      foo
      是不同的函数(尽管它们有相同的名称)。我所说的调试器打印名称的意思是,您放在
      函数
      右侧的名称显示在堆栈跟踪上。如果你什么都不放,它只会显示
      匿名函数
      ,这有点道理你完全正确。如果通过函数声明或将命名函数表达式赋给变量给函数一个名称,则调试器应显示该名称。函数有(1)一个可选名称,(2)零个或多个参数,(3)一个主体。由于名称是可选的,调试器将显示名称(如果有),否则显示“匿名函数”。+1表示链接。它几乎满足了我的需要谢谢@Ray!顺便说一句,在某些IE版本(可能只有6个)中,命名函数表达式存在一些问题。它将创建两个实例(每个名称一个实例),而不是两个名称一个实例。