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

Kev*_*son 105 javascript syntax anonymous-function iife

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

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

(function () {
  // code here
})();
Run Code Online (Sandbox Code Playgroud)

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

(function () {
  // code here
}());
Run Code Online (Sandbox Code Playgroud)

有通过CMS在接受答案的注释解释JavaScript的封装匿名函数的语法是"既:(function(){})();(function(){}());有效."

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

med*_*iev 64

他们几乎是一样的.

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

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

我不认为有一种"正确"的方式,因为表达的结果是相同的.

> function(){}()
SyntaxError: Unexpected token (
> (function(){})()
undefined
> (function(){return 'foo'})()
"foo"
> (function(){ return 'foo'}())
"foo"
Run Code Online (Sandbox Code Playgroud)

  • @ XP1:JSLint需要许多特定于Crockford*style*的东西而不是实质性的东西.这是其中之一. (48认同)
  • 实际上你不仅限于这两个,你可以使用任何使编译器实现函数是表达式而不是语句的任何东西,例如`+ function(){}()`或`!function() {}()`. (27认同)
  • JSLint想要"(function(){}());".JSLint说,"将调用移动到包含该函数的parens中." (8认同)
  • @ThorpeObazee:真的没关系,所以你喜欢什么.我建议不要使用一些更多的东西(`-function(){}();`,`!function(){}();`,基本上在`function`之前的任何其他运算符也可以工作,但是我坚持使用parens的版本.我看到第一个*很多*比我看到第二个更多,这是我的偏好; 它对我来说也更有意义,但这是主观的.FWIW:http://jsbin.com/ejaqow (4认同)

Tri*_*ych 13

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

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

(foo || bar)()
Run Code Online (Sandbox Code Playgroud)

  • 为了澄清其他读者(主要是因为我起初并不理解它:)),foo和/或bar必须已经等于某些功能.(例如`foo = function(){alert('hi');}`.如果两者都不是函数,则抛出错误. (3认同)
  • @AlexanderBird进一步说明 - 如果`foo`是"真理"而不是函数,它也会抛出错误. (2认同)

Cri*_*hez 9

语法之外没有任何区别.

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

考虑:

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

namedfunc即使您提供了名称,它仍然不会在全球范围内.匿名函数也是如此.获得该范围的唯一方法是将其分配给parens内的变量.

((namedfunc = function namedfunc () { ... })())
Run Code Online (Sandbox Code Playgroud)

外围是不必要的:

(namedfunc = function namedfunc () { ... })()
Run Code Online (Sandbox Code Playgroud)

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

所以它归结为:

(function namedfunc () { ... })()
Run Code Online (Sandbox Code Playgroud)

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

(function () { ... })()
Run Code Online (Sandbox Code Playgroud)

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


归档时间:

查看次数:

12274 次

最近记录:

8 年,8 月 前