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

发布于 2024-09-12 13:22:00 字数 612 浏览 4 评论 0原文

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

以前的代码将匿名函数括在括号中然后执行它,

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

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

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

CMS在解释JavaScript的封装匿名函数语法 “(function(){})();(function(){}()); 都是有效的。”

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

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.

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.”

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

独木成林 2024-09-19 13:22:00

它们几乎是一样的。

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

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

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

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

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"
孤独岁月 2024-09-19 13:22:00

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

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

(foo || bar)()

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)()
忆依然 2024-09-19 13:22:00

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

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

考虑:

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

namedfunc 即使仍然不在全局范围内尽管你提供了名字。匿名函数也是如此。将其置于该范围内的唯一方法是将其分配给括号内的变量。

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

外括号是不必要的:

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

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

所以它归结为:

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

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

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

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

There isn't any difference beyond the syntax.

Regarding your concerns about the second method of doing it:

Consider:

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

晨曦÷微暖 2024-09-19 13:22:00

差异的存在只是因为 Douglas Crockford 不喜欢 IIFE! (严肃地)正如您在此视频中看到的那样!!

{两种样式}中存在额外包装 () 的唯一原因是帮助使该部分代码函数表达式,因为函数声明 无法立即调用。一些脚本/缩小器只使用 +!- & ~ 而不是太括号。像这样:

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

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

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

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

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

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

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 ;-) }

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文