2012-02-03 78 views
4

可能重复:
What do parentheses surrounding a JavaScript object/function/class declaration mean?在JavaScript的什么呢(......)做的正是

与同事,这是最好

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

最近讨论
(function(){...})() 

我不知道在基本级别实际做了什么(...),以及在上述情况下js引擎的作用有什么区别。理论上(即使只有一小部分)比另一个更快吗?如果我的函数返回一个对象,那么(..)在第一个示例中对该对象做了什么?

任何人都可以解释。

*编辑我在网上最接近的一个解释是http://dmitrysoshnikov.com/ecmascript/chapter-5-functions/#question-about-surrounding-parentheses,但在我看来,这样做可以简单地解释为什么上面的第一个例子可以工作。

+0

即使表现有差异(我非常怀疑,但是出于参数的原因),**并不重要。**您将操纵DOM对象,循环播放等等。我们在这里谈论的是数百万到数十亿的CPU周期。除非你正在运行一些延迟的微基准测试,否则你将永远不会注意到你可能会保存的周期。 – cHao 2012-02-03 15:08:11

+0

对性能的原因我并不感兴趣(尽管我很好奇是否有最小的性能差异) - 我只是想知道js引擎在解释(...)时会做什么(...) – wheresrhys 2012-02-03 15:09:55

+0

在几乎所有情况下, '(x)'和'x'在语法上是有效的,'(x)'完全等同于'x'。我知道的唯一例外是函数声明,它实际上是非法的表达式的一部分,但是当用括号或其他方式用作表达式的一部分时,函数声明变为函数*表达式*。这有点奇怪,但它有效。 – cHao 2012-02-03 15:13:55

回答

2

第一个示例的工作原理与第二个示例的工作原理完全相同。没有真正的区别。这也适用于:

!function() { ... }(); 

所以做这个的:

var _dont_care_ = function() { ... }(); 

关键是要安排function关键字来声明在一个点出现在解析器知道它不能开始一个函数声明语句。在这种情况下,function关键字必须在表达式中将函数对象实例化为

除了表达式语句之外,JavaScript中的语句以关键字开头(暂时留下标签)。在不是function关键字(这里是一个肢体)开始的任何语句中,function可能意味着的唯一事情就是函数对象值的实例化。

+0

因此,除了使表达式在语法上正确之外,不需要关闭)。奇怪的东西。 – wheresrhys 2012-02-03 15:35:33

+0

是的。基本上,你只需要让解析器知道'function'关键字没有开始自己的语句。因此,举个例子,如果你想要在'for'循环头的表达式之一中使用“裸”函数表达式,因为函数定义不会在那里发生。 – Pointy 2012-02-03 15:59:12

3

你根本不需要括号。这些括号的整个想法是强制一个函数是一个expression而不是一个声明。您也可以做到这一点像

!function() { 
}(); 

这exclamationmark也可能是+-和一些其他字符。所以,你是否使用“狗球”版本(你的后一款)没有区别。从性能方面来说,我不能保证,但我99.9%肯定没有差别(最好是引擎依赖的变化)。

因此,如果我们假设这两者之间没有性能差异,那么您使用哪一个更偏好个人偏好。 Crock多次宣称第二个版本为“狗球”,因为您不再包装整个表达式。我同意这一点。如前所述,模式只是强制一个函数表达式,它应该封装整个事物以提高可读性。

+0

使用'+'或'-'而不是'!'会导致问题。考虑'var x = 42/*换行符,但不能使用分号* /!function(){...}()'。如果用'+'替换'!',它将变成一个二元运算符,并且函数调用的结果成为'x'的值的一部分。 – 2012-02-03 15:14:24

+0

@Mike:这就是为什么人们应该使用分号。 :P分号插入是将它变成真正的编程语言的最糟糕的想法之一。如果有人利用它,我几乎认为他们从来没有写过任何严重的JS代码。 – cHao 2012-02-03 15:23:15

+0

@cHao,人们忘记了分号,所以我只是建议坚持习惯用法,以尽量减少混淆的可能性。 – 2012-02-03 15:26:59