匿名函数与正常函数

时间:2012-11-10 15:13:09

标签: javascript function anonymous-function

出于兴趣,

之间是否有任何速度/功能差异
function foo(bar) {
    alert("foo" + bar);
}

var foo = function(bar) {
    alert("foo" + bar);
};

1 个答案:

答案 0 :(得分:25)

没有明显的速度差异。 (Test

存在功能差异。

  • 函数声明(就像你的第一个)和函数表达式(比如你的第二个)在不同的时间处理。
  • 它们对其发生的范围有不同的影响。
  • 您的第一个函数在ES5及更早版本中有真名称您的第二个函数,而您的第二个函数没有;在ES6 / ES2015中,确实如此,因为规范说JavaScript引擎必须在这种情况下将变量的名称赋给函数。

如果您四处寻找“功能声明”与“功能表达”,您会在主题上找到很多的谈话(其中一些甚至是正确的)。

但简单地说:

功能声明

一个函数声明就像你的第一个例子在执行游标进入其包含范围(包含函数或全局范围)之前发生的,在完成任何分步代码之前。因此,它们不能出现在非功能块(iftry等)中,因为在处理它们时没有运行逐步代码。函数的名称被添加到它出现的范围中,并且函数对象具有真实的名称(虽然没有标准的方法来查询该名称,它在堆栈跟踪等方面仍然有用) 。 (注意:有些JavaScript引擎允许在块内执行函数声明,但它无效,它们的作用不一定一致。不要这样做。)

匿名函数表达式

像第二个例子一样,函数表达式就像所有表达式一样,在代码的逐步流程中遇到它。您的表达式称为匿名函数表达式,因为它没有明确指定函数的名称。在ES5及更早版本中,这意味着生成的函数没有名称。在ES6 / ES2015及更高版本中,使用匿名函数表达式 do 创建的许多函数都有名称,因为名称可以从表达式中推断出来,这就是您的示例的情况,其中函数最终以将变量命名为:foo。由于匿名函数表达式是表达式,它们可以出现在任何表达式都可以发生的地方,尽管有时您必须警告解析器这就是您正在做的事情。

命名函数表达式

还有第三种方法:名为的函数表达式,而不是匿名函数。它们看起来像这样:

var foo = function bar() {
};

var obj = {
    foo: function bar() {
    }
};

doSomething(function bar() { });

他们曾经是真正有问题的跨浏览器(例如IE8和早期的mess them up;早期版本的Safari存在问题等; Kangax有a good page的过去常见的问题)。它是一个表达式,因此只要有表达式,它就是有效的。 函数名称(我的示例中为bar由兼容的JavaScript引擎添加到包含范围。