用于自动执行匿名JavaScript函数的括号的位置?

时间:2010-08-02 01:39:39

标签: javascript syntax anonymous-function iife

我最近将当前版本的json2.js与我项目中的版本进行了比较,并注意到函数表达式的创建和自行执行方式有所不同。

用于在括号中包装匿名函数然后执行它的代码,

(function () {
  // code here
})();

但现在它将自动执行的函数包装在括号中。

(function () {
  // code here
}());

CMS在Explain JavaScript’s encapsulated anonymous function syntax的接受答案中有一条评论“(function(){})();(function(){}());都有效。”

我想知道区别是什么?前者是否通过绕过全局匿名函数来占用内存?括号应该放在哪里?

4 个答案:

答案 0 :(得分:62)

他们几乎是一样的。

第一个包围函数的括号,使其成为有效的表达式并调用它。表达式的结果是未定义的。

第二个执行函数,自动调用周围的括号使其成为有效的表达式。它还评估为undefined。

我认为没有一种“正确”的方式,因为表达的结果是相同的。

> function(){}()
SyntaxError: Unexpected token (
> (function(){})()
undefined
> (function(){return 'foo'})()
"foo"
> (function(){ return 'foo'}())
"foo"

答案 1 :(得分:13)

在这种情况下无所谓。您正在调用一个表达式,该表达式解析为第一个定义中的函数,并在第二个示例中定义并立即调用函数。它们是相似的,因为第一个例子中的函数表达式只是函数定义。

还有其他更明显有用的案例用于调用解析为函数的表达式:

(foo || bar)()

答案 2 :(得分:8)

语法之外没有任何区别。

关于您对第二种方法的担忧:

考虑:

(function namedfunc () { ... }())

即使您提供了名称,

namedfunc仍然不在全球范围内。匿名函数也是如此。获得该范围的唯一方法是将其分配给parens内的变量。

((namedfunc = function namedfunc () { ... })())

外围的parens是不必要的:

(namedfunc = function namedfunc () { ... })()

但你还是不想要那个全球宣言,是吗?

所以归结为:

(function namedfunc () { ... })()

你可以进一步减少它:名称是不必要的,因为它永远不会被使用(除非你的函数是递归的......即使这样你也可以使用arguments.callee

(function () { ... })()

这就是我想到的方式(可能不正确,我还没有读过ECMAScript规范)。希望它有所帮助。

答案 3 :(得分:-3)

之所以存在差异,是因为道格拉斯·克罗克福德不喜欢 IIFEs的第一种风格! (seriuosly)As you can see in this video!!

在两种样式中存在额外包装() {的唯一原因是帮助制作代码部分功能表达式,因为功能声明不能马上打电话。一些脚本/缩小器只使用+!-& ~而不是括号。像这样:

+function() {  
    var foo = 'bar';  
}();

!function() {  
    var foo = 'bar';  
}();

-function() {  
    var foo = 'bar';  
}();

~function() {  
    var foo = 'bar';  
}();

所有这些都与您的选择完全相同。在这些案例中进行选择完全取决于你自己和他们。没有区别。 ()生成 1字节更大的文件 ;-)}