What determines if a JavaScript function is a named anonymous function versus a, um, regular function?
阅读"重新介绍JavaScript"我注意到一些有关函数的有趣内容:
The name provided to an anonymous function as above is(or at least should be) only available to the function's own scope.
根据nodejs提示中教程中的代码输入一些内容我能够验证该节点是否与作者一致:
1 2 3 4 5
| function add(foo, bar) {
return foo + bar;
}
add(1, 2); |
得到我3,并:
1 2 3 4
| var five = (function plus(foo, bar) {
return foo + bar;
})(2, 3);
plus(2, 3); |
给我一个关于加上未定义的语法错误。
我有点困惑,因为我用来定义两个函数的代码是相同的(名称除外)。 JavaScript如何知道第一个是常规函数,第二个是命名匿名函数?
-
"匿名命名":)它不可能两者兼而有之。
-
@pimvdb确实。 它实际上是一个命名函数表达式,而不是一个匿名函数。
-
@pimvdb:哈哈,我知道,对吗? 但这就是文章所称的内容。 我不认为您知道ECMA称之为什么?
-
@Samuel Edwin Ward:我相信这是一个函数声明与一个函数表达式。 问题是只有函数表达式才能是匿名的。 事实上通常就是这种情况,显然他们(错误地)成了同义词。
第一个是正常的函数声明。声明的名称被引入当前作用域,并隐式引用函数体。在这种形式中,function是一个语句,因此不返回任何值。
第二个是函数表达式,解释器知道这是因为它是赋值的右侧的一部分,并且因为它周围的括号。任何时候单词function出现在其他某个"值"(或"表达式")可能已经提供的地方,那么你所拥有的是一个函数表达式。该表达式的结果是对函数体的引用。
函数表达式的名称(如果它被赋予一个)仅在函数中可用,如链接中所述。
恕我直言,该链接的命名是不正确的。在我看来,他们所谓的"命名匿名函数"应该被称为"命名函数表达式"。这个明显的错误可能源于所有匿名函数实际上都是函数表达式,但并非所有函数表达式都是匿名的。
请注意,如果您使用此样式:
1 2 3
| var foo = function bar() {
...
} |
然后如上所述bar是函数表达式,其结果然后被赋值给变量foo。名称bar未放入当前范围,但在函数本身中可用。
变量foo的声明将被提升到作用域的顶部,但不会被赋予其值(即对函数表达式的引用),直到实际执行上面的行。
另一个有趣的示例是(从Chrome控制台):
1 2 3 4
| > function() { }
SyntaxError: Unexpected token (
> a = function() { }
function () { } |
请注意,唯一的区别是后者有一个a的赋值。尝试使用语句声明匿名函数是非法的,因为语言语法要求函数语句包含函数的标签。然而,后者隐式地是一个函数表达式,允许它是匿名的。
-
我已经提出了这个答案,因为它表明了对手头主题的清晰认识以及解释它的不起眼的技巧。我也同意"命名匿名函数"这个短语是矛盾的。分配给另一个名称变量的"命名函数表达式"(的值)的例子非常适合解释这里发生的事情。但我仍然感到不知道为什么(或者也许是如何)。 [继续]
-
"因为它是作业右侧的一部分,并且因为它周围的支撑。"我假设"括号"你的意思是ASCII 40和41?你的解释是否必要且充分?你能引用章节和经文吗?如果我在函数调用中提供有问题的代码作为参数,没有括号,并且没有将它赋给变量,那么它是函数声明还是命名函数表达式?
-
@SamuelEdwinWard也是一个函数表达式。通常只有语法function foo() { ... }是一个普通的函数声明,提示是function标记是语句中的第一个东西。几乎任何东西都是函数表达式。我认为反义部分来自所有匿名函数实际上是函数表达式,但并非所有函数表达式都是匿名的。
-
@SamuelEdwinWard最终归结为语言语法。函数声明完全按照它所说的完成,而不再是它。它将变量引入范围。但是,只要你在一个预期值(即表达式)的地方输入单词function,那么它就是一个函数表达式。由于()的内容必须是表达式,因此其中的任何函数都是函数表达式。
-
@SamuelEdwinWard我想你可能在寻找这个:ecma-international.org/ecma-262/5.1/#sec-13
-
@Geoff,我认为一定是ecma-international.org/ecma-262/5.1/#sec-12.4