匿名函数与普通函数 [英] Anonymous function vs normal function

查看:25
本文介绍了匿名函数与普通函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

只是出于兴趣,两者之间是否存在速度/功能差异

Just out of interest, are there any speed/functionality differences between

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

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

推荐答案

没有明显的速度差异.(测试)

There are no significant speed differences. (Test)

存在功能差异.

  • 函数声明(如您的第一个)和函数表达式(如您的第二个)在不同时间处理.
  • 它们对发生的范围有不同的影响.
  • 在 ES5 及更早版本中,您的第一个函数具有 真实名称您的第二个没有,您的第二个没有;在 ES6/ES2015 中,确实如此,因为规范规定 JavaScript 引擎在这种情况下必须将变量的名称分配给函数.
  • Function declarations (like your first) and function expressions (like your second) are processed at different times.
  • They have different effects on the scope in which they occur.
  • Your first function has a true name, your second does not in ES5 and earlier, your second does not; in ES6/ES2015, it does, because the specification says that the JavaScript engine must assign the name of the variable to the function in that case.

如果您四处寻找函数声明"与函数表达式",您会发现关于该主题的很多讨论(其中一些甚至是正确的).

If you look around for "function declaration" vs. "function expression" you'll find a lot of talk (some of it even correct) on the topic.

但简单地说:

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

A function declaration like your first example happens when the execution cursor enters its containing scope (containing function or the global scope), before any step-by-step code is done. Therefore they cannot appear within non-function blocks (if, try, etc.), since no step-by-step code has been run when they're processed. The name of the function is added to the scope in which it appears, and the function object has a true name (although there's no standard way to query that name, it's still useful in stack traces and such). (Note: Some JavaScript engines allow function declarations within blocks, but it's invalid and what they do is not necessarily consistent. Don't do it.)

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

A function expression like your second example happens, like all expressions, when it's encountered in the step-by-step flow of the code. Your expression is called an anonymous function expression since it doesn't explicitly specify a name for the function. In ES5 and earlier, that meant that the resulting function had no name. In ES6/ES2015 and later, many functions created with anonymous function expressions do have names because the name can be inferred from the expression, and that's the case with your example, in which the function ends up with the name the variable has: foo. Since anonymous function expressions are expressions, they can occur anywhere expressions can occur, although sometimes you have to warn the parser that that's what you're doing.

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

There's a third way of doing this: A named function expression, rather than an anonymous one. They look like this:

var foo = function bar() {
};

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

doSomething(function bar() { });

它们曾经确实有问题的跨浏览器(IE8 和更早版本的搞砸;Safari 的早期版本有问题,等等;Kangax 有 一个很好的页面过去比比皆是的问题).它是一个表达式,所以它在任何有表达式的地方都有效.函数名称(在我的示例中为bar)不会被兼容的 JavaScript 引擎添加到包含范围.

They used to be really problematic cross-browser (IE8 and earlier mess them up, for instance; early versions of Safari had issues, etc.; Kangax has a good page of the problems that used to abound). It's an expression, so it's valid anywhere there's an expression. The function name (bar in my example) is not added to the containing scope by a compliant JavaScript engine.

这篇关于匿名函数与普通函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆