为什么在调用JavaScript函数时要使用括号?

30

这两个JavaScript函数调用之间有什么区别?

(function(){alert("foo")})()

相对于这个:

(function(){alert("foo")}()) 

我认为这两者意思相同,换句话说,它们是一样的。 - Sai Kalyan Kumar Akshinthala
区别只是很小的风格问题。有些人喜欢在分组运算符内(例如Douglas Crockford)编写形式参数列表(也称“调用运算符”),而有些人则喜欢将其放在外面。这并没有什么实际区别 - 请尝试Ben Alman的立即调用函数表达式 - RobG
2个回答

28

这么做是为了可读性。

你给出的两个例子没有真正的功能区别,但它们都非常接近于一个简单的函数声明,而这是不同的。添加括号是为了增加可读性以便区分它们。

以下是你的代码片段各自的作用:

在你给出的第一个代码片段中,第一个括号将被评估为包含的函数的值。然后该值将被作为函数调用。因此最终将执行该函数,这可能是你关心的。

在你的第二个代码片段中,外部括号将被评估为内联声明并立即执行的函数。同样,该函数将被执行,这仍然可能是你关心的。

这两种方法都将执行相同的函数,所以没有任何显著的区别。

这样做与简单函数声明之间的区别:

你给出的函数也与以下函数相同。我只是添加了一个函数名并分配了返回值以进行语法上的准确性,你现在可以忽略它。

// javascript...
var val = 
  function myFooFunc () { 
    alert("foo"); 
  }();

然而,这很容易被误解为一个简单的函数声明,但实际上它们是不同的:

// javascript...
function myFooFunc () { 
  alert("foo"); 
}
请注意,这里唯一的真正差异在于,最后一个函数声明不会立即执行,而其他函数则会被执行。因此,这是非常不同的行为(如果通过名称调用简单声明,则可能稍后执行,或者根本不会执行)。然而,特别是如果函数体变得非常长并需要在屏幕上滚动,往往很难立即看出语法上的区别。
为什么函数要立即执行?
当函数在声明后立即执行时,通常返回值被传递给某个东西(它可能是赋值语句的一部分)。有时,函数被立即执行,因为它包含内部函数,并且正在被用来为封闭语句提供函数作用域。
实际上,人们在“立即执行”形式周围加括号(你的两个片段和我的两个片段中的第一个)是为了向其他开发人员提供视觉提示,表明该函数正在被立即调用。这样做更容易阅读,因为您可能直到函数末尾(或根本没有注意到)才注意到括号。

我在你的第一个代码片段中遇到了语法错误。但是当我在第一个代码片段函数前面放置变量时,它可以正常工作。 - Dexy_Wolf
2
@Dejan - 这是因为第一个例子语法错误。函数声明后面不能跟着一个分组运算符。在function关键字之前的"("将其改变为函数表达式,并且当然需要一个匹配的闭合")"。一旦改为函数表达式,函数名就变成可选的了。 - RobG
是的,我在第一个片段中去掉了外部括号,以便更加关注它与第二个片段之间的区别。不过,根据您的评论,我认为如果示例不能作为独立片段运行,这可能最终会更具有分散注意力的作用。为了解决这个问题,我对第一个片段进行了小修改,希望不会太分散注意力,但允许第一个片段完全有效。 - keparo

8

它们都有类似的行为。

括号包含函数声明,告诉JavaScript引擎在解析后立即执行代码。在第一个例子中,你正在创建一个函数对象,然后使用其后面的括号调用它。在第二个例子中,你告诉JavaScript引擎创建函数对象并立即调用它。

例子:

// creates a function object
var f1 = (function() { alert('foo'); }); 

// creates a function object and executes it immediately
var f2 = (function() { alert('foo'); }()); 

它们的区别在于f1会给你一个函数对象,而f2则创建并调用一个匿名函数。


7
这两个例子中都不需要使用组合运算符,它只是为了增加可读性而被使用。它们的不同之处在于第一个例子把函数赋值给变量,而第二个例子则将调用函数后的结果赋值给变量。 - RobG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接