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

时间:2021-04-30 22:29:51

I was recently comparing the current version of json2.js with 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 syntax that “both: (function(){})(); and (function(){}()); are valid.”

CMS在解释JavaScript的封装匿名函数语法的接受答案中有一条评论:“both:(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?

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

4 个解决方案

#1


62  

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.

第二个执行函数,自动调用周围的括号使其成为有效的表达式。它还评估为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"

#2


13  

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)()

#3


7  

There isn't any difference beyond the syntax.

语法之外没有任何区别。

Regarding your concerns about the second method of doing it:

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

Consider:

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

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

namedfunc will 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仍然不在全局范围内。匿名函数也是如此。在该范围内获取它的唯一方法是将其分配给parens中的变量。

((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规范)。希望能帮助到你。

#4


-3  

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

差异只是因为道格拉斯·克罗克福德不喜欢IIFE的第一种风格! (seriuosly)正如你在这个视频中看到的!!

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 Declaration cannot be immediately called. Some scripts / minify-ers just use +, !, - & ~ instead of too parentheses. Like this:

在两个样式中存在额外换行()的唯一原因是帮助使代码段功能表达式,因为无法立即调用函数声明。有些脚本/缩小器只使用+,!, - &〜而不是括号。像这样:

+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字节更大的文件;-)}

#1


62  

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.

第二个执行函数,自动调用周围的括号使其成为有效的表达式。它还评估为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"

#2


13  

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)()

#3


7  

There isn't any difference beyond the syntax.

语法之外没有任何区别。

Regarding your concerns about the second method of doing it:

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

Consider:

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

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

namedfunc will 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仍然不在全局范围内。匿名函数也是如此。在该范围内获取它的唯一方法是将其分配给parens中的变量。

((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规范)。希望能帮助到你。

#4


-3  

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

差异只是因为道格拉斯·克罗克福德不喜欢IIFE的第一种风格! (seriuosly)正如你在这个视频中看到的!!

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 Declaration cannot be immediately called. Some scripts / minify-ers just use +, !, - & ~ instead of too parentheses. Like this:

在两个样式中存在额外换行()的唯一原因是帮助使代码段功能表达式,因为无法立即调用函数声明。有些脚本/缩小器只使用+,!, - &〜而不是括号。像这样:

+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字节更大的文件;-)}