有两种方法可以在 JavaScript 中实例化函数。它们看起来一样,但它们的含义并不完全相同。
您发布的是作为语言表达式一部分的函数实例化。在这种形式下,语法是
函数 名 ( p1 , p2 , ... ) { body }
“名称”和参数是可选的;关键字function
和括号是必需的。(在这种情况下,在某些浏览器中使用名称存在一些晦涩难懂的问题;问题越来越少了。)
这样做的效果是创建一个新的函数对象。对对象的引用就像任何其他值一样参与到表达式中(嗯,就像对对象的任何其他引用一样)。因为它是一个函数,所以引用也可用于调用函数并使其代码(“主体”)执行,就像您所期望的那样。(如果你不能,它就不会是一个很大的功能!)
可以实例化函数的另一种方法是使用函数声明语句,令人惊讶的是,它看起来完全一样(除了需要“名称”)。不同之处在于关键字function
出现在代码中的确切位置:
如果关键字function
是新语句中的第一件事,那么你有一个函数声明并且“名称”是必需的。在这种情况下,该语句不是表达式语句,并且该语句唯一要做的就是实例化函数并将对该函数的引用绑定到“name”或多或少,就好像“name”是一个局部变量(或 global if in全局范围)。
如果关键字function
出现在表达式中的任何其他位置(表达式语句,或者埋在其他上下文中的表达式,例如for
或while
循环语句的顶部),那么它就是函数实例化表达式。
现在,不管函数是如何“诞生”的,一旦你获得了对该函数的引用,你就可以调用它并传递任意数量的参数。
我个人不知道这种趋势是如何开始的,或者它是否应该被视为一种趋势,但是看到用这样的代码实例化的本地函数是相当普遍的(就像你发布的那样):
var some_function = function( arg1, arg2 ) {
/* some code */
};
这是表达式中函数实例化的示例。最终效果是符号“some_function”绑定到新创建的函数。但是,名称与(几乎)等效函数声明中的函数绑定的方式之间存在细微的差异:
function some_function( arg1, arg2 ) {
/* some code */
};
第二种方式(函数声明语句)更好一点的一个简单原因是函数的名称将显示在堆栈跟踪中。当然,可以通过冗余外观来实现:
var some_function = function some_function( arg1, arg2 ) {
/* some function */
};
我真的不知道您为什么要这样做,但它会起作用,除非在一些顽皮的环境中。