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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3384504/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 01:02:28  来源:igfitidea点击:

Location of parenthesis for auto-executing anonymous JavaScript functions?

javascriptsyntaxanonymous-functioniife

提问by Kevin Hakanson

I was recently comparing the current version of json2.jswith the version I had in my project and noticed a difference in how the function expression was created and self executed.

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

The code used to wrap an anonymous function in parenthesis and then execute it,

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

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

but now it wraps the auto-executed function in parenthesis.

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

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

There is a comment by CMS in the accepted answer of Explain JavaScript's encapsulated anonymous function syntaxthat “both: (function(){})();and (function(){}());are valid.”

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

I was wondering what the difference is? Does the former take up memory by leaving around a global, anonymous function? Where should the parenthesis be located?

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

采纳答案by meder omuraliev

They're virtually the same.

它们几乎相同。

The first wraps parentheses around a function to make it a valid expression and invokes it. The result of the expression is undefined.

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

The second executes the function and the parentheses around the automatic invocation make it a valid expression. It also evaluates to undefined.

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

I don't think there's a "right" way of doing it, since the result of the expression is the same.

我不认为有一种“正确”的方法可以做到,因为表达式的结果是相同的。

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

回答by Triptych

In that case it doesn't matter. You are invoking an expression that resolves to a function in the first definition, and defining and immediately invoking a function in the second example. They're similar because the function expression in the first example is just the function definition.

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

There are other more obviously useful cases for invoking expressions that resolve to functions:

对于调用解析为函数的表达式,还有其他更明显有用的情况:

(foo || bar)()

回答by Cristian Sanchez

There isn't any difference beyond the syntax.

除了语法之外没有任何区别。

Regarding your concerns about the second method of doing it:

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

Consider:

考虑:

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

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

namedfuncwill still not be in the global scope even though you provided the name. The same goes for anonymous functions. The only way to get it in that scope would be to assign it to a variable inside the parens.

namedfunc即使您提供了名称,也不会在全局范围内。匿名函数也是如此。在该范围内获取它的唯一方法是将其分配给括号内的变量。

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

The outer parens are unnecessary:

外部括号是不必要的:

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

But you didn't want that global declaration anyways, did you?

但无论如何你都不想要那个全局声明,是吗?

So it it boils down to:

所以它归结为:

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

And you can reduce it even further: the name is unnecessary since it will never be used (unless your function is recursive.. and even then you could use arguments.callee)

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

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

That's the way I think about it (may be incorrect, I haven't read the ECMAScript specification yet). Hope it helps.

这就是我的想法(可能不正确,我还没有阅读 ECMAScript 规范)。希望能帮助到你。

回答by Behrad Khodayar

The difference just exist because Douglas Crockford doesn't likethe first style for IIFEs! (seriuosly) As you can see in this video!!.

之所以存在差异,是因为道格拉斯·克罗克福德 (Douglas Crockford)不喜欢IIFE的第一种风格!(严肃地)正如你在这个视频中看到的那样!!.

The only reason for the existence of the extra wrapping (){in both styles} is to help make that section of code Function Expression, because Function Declarationcannot be immediately called. Some scripts / minify-ers just use +, !, -& ~instead of too parentheses. Like this:

存在额外包装(){in both styles}的唯一原因是帮助制作该部分代码Function Expression,因为无法立即调用Function Declaration。一些脚本/缩小器只是使用+, !, -&~而不是括号。像这样:

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

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

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

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

And all these are exactly the same as your alternatives. Choosing among these cases is completely on your own & makes no difference. { The ones with ()produce 1 Byte larger File;-) }

所有这些都与您的选择完全相同。在这些案例中进行选择完全由您自己决定,没有任何区别。{()产生1 字节大文件的文件;-) }