这是一个函数表达式2
函数表达式也可以有名称;函数表达式的名称仅在函数体1的范围内。(由于 ECMAScript 第 5 版弃用arguments.callee
了 ,这是编写递归“匿名”函数的唯一简单方法。)
因为它是一个函数表达式,所以名称可能不会1在外部范围内引入新的绑定。
此外,所有函数都是 JavaScript 中的对象。在f(..)
,在它被“调用”之前f
被评估; 如果没有对函数求值,则会引发错误。这就是为什么回调,只是函数,可以通过变量命名并作为参数传递。(..)
f
另外,检查关于原型的假设/断言:
var abc = function def() {}
abc.prototype === abc // -> false
abc.name // -> "def"
1见 Bergi 的回答。
2如何轻松分辨哪个是哪个?
语法规则仅允许function ..
在它是SourceElement时将其解析为 Function Declaration ,尽管大多数引擎仍会 [不正确地] 将 Function Declaration 解析为Statement。SourceElement 产生只发生在程序的顶级“块”或函数的顶级“块”。
在任何情况下,只要function ..
出现在需要Expression的地方,它就会被解析为函数表达式。全部解析为函数表达式的示例:
// Can only assign values: Statements do not have values!
var f = function () {}
var g = function gName () {} // see Bergi's answer
// Can only pass values: Statements do not have values!
doIt(function () {}) // callback / "anonymous function"
// IIFE: Immediately-Invoked Function Expression
;(function () {})() // standard IIFE
;(function () {} ()) // alternative standard IIFE
;+function () {} () // curious way to write an IIFE
// basically you can use any unary operator to turn it into an expression not only
// + but also - ! ~ and so on which will modify the return value accordingly
关键是,在上述每一种情况下,都function ..
出现在需要表达式的语法位置,因此被解析为函数表达式。(上面行开头的分号避免了与 ASI 的“歧义”,这在像我喜欢的那样以无分号风格编写时是必需的。)
然而。;function () {} ()
并且;function f () {} ()
都是无效的语法 - 为什么?;-)