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

时间:2022-06-28 01:35:50

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的当前版本。在我的项目中使用的版本,并注意到函数表达式的创建和自执行方式的差异。

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在Explain JavaScript封装的匿名函数语法中给出了一个评论:“both: (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


60  

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"

#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 () { ... }())

(函数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仍然不会在全局范围内。匿名函数也是如此。在这个范围内获得它的唯一方法是将它分配给参数中的一个变量。

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

而且您可以进一步减少它:名称是不必要的,因为它永远不会被使用(除非您的函数是递归的)。即使这样,你也可以用论点。

(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!!.

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

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


60  

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"

#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 () { ... }())

(函数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仍然不会在全局范围内。匿名函数也是如此。在这个范围内获得它的唯一方法是将它分配给参数中的一个变量。

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

而且您可以进一步减少它:名称是不必要的,因为它永远不会被使用(除非您的函数是递归的)。即使这样,你也可以用论点。

(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!!.

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

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