2012-02-03 75 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