2011-09-08 60 views
2

我在理解這兩行如何互換方面遇到了一些麻煩。自我調用匿名函數解析問題

(function() { return console.log("anon inner 1"); })(); 
//              ^^ invoke 

(function() { return console.log("anon inner 2"); }()); 
//             ^^ invoke 

在第一行中,我們有一個匿名內部函數,它包裝在括號中,然後立即調用。第二行,我們有一個匿名的內部函數被調用,然後包裝在圓括號中。

我想我的問題是,括號中的包裹是做什麼的?它是否將物體客觀化,即將事物變爲物體?

+0

http://jsbin.com/orobok/edit#javascript,html – weisjohn

+1

請參見http://計算器.com/questions/3384504 /括號內的自動執行位置 - 匿名 - javascript-functions –

回答

3

JavaScript有一個功能statement,這是「標準」的方式來聲明一個函數,與語法:

function name([param1, 2...]) { 
    statements 
} 

而且還有一個功能operator,看起來一樣的函數聲明除了名稱是可選的,它不是用來作爲自己的一個聲明,但其中一個表達預計在下面兩個例子:

// declare variable name that references a function created by expression 
var name = function([param1, 2...]) { statements }; 
// call someOtherFunction that expects a function as a parameter 
someOtherFunction(function() { }); 

(有很多其他的方式來使用函數表達式。)

如果試圖對自身行匿名函數,而不在括號包裹它,它會認爲是一個功能聲明,因而是一個語法錯誤,因爲沒有名字。用括號括起來意味着它將被視爲表達式在parens中,而不是作爲一個語句,所以名稱是可選的。如果你將函數表達式的結果賦值給一個變量或者以其他方式使用它(就像在上面的例子中那樣),那麼你不需要括號。

因此,最後得到問題中提到的語法:一旦你有parens並且你的函數被視爲一個表達式,你可以使用你發佈的兩種語法之一來調用它。首先,調用parens的「outside」意味着第一組parens將評估爲具有內部表達式的值,這恰好是可以調用的函數。第二,調用「內部」意味着函數表達式將被調用,然後周圍的parens將評估任何函數返回。

無論哪種方式,函數的返回值都會被丟棄,因爲您不會將其分配給任何東西。

(最後提示:函數表達式可以有一個名稱,以便函數可以遞歸調用本身)

1

當你有像一個普通的annon功能:

function() { alert('testing'); } 

這是一個函數表達式。任何其他vairiation被稱爲函數聲明,如下所示:

function a() { alert('testing'); } 
!function() { alert('testing'); } 
var a = function { alert('testing'); } 
(function() { alert('testing'); }) 

現在函數表達式不能因爲它不是一個返回值調用,但聲明即可。因此,您只需將其切換到聲明即可調用,這是parens所做的,無論它們是否包裝調用的parens。這是因爲一旦js解析器看到一個開放的parens,它就會將其變爲聲明

聲明:我可能混合起來聲明表達的術語

+2

更多:https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope另外,請注意表單函數a(){}'將自己提升到定義範圍的頂部,並覆蓋任何變量,例如'var a = 0'。例如:http://jsfiddle.net/G8ydD/控制檯應該顯示一個'TypeError',因爲它試圖調用數字0作爲函數。 –

+0

謝謝,吉姆!只是看看那個jsfiddle,事實上,它拋出了那個錯誤。我實際上剛剛在今晚學習了這個概念,因爲我正在關注Crockford關於JavaScript第3部分的鏈接(http://yuilibrary.com/theater/douglas-crockford/crockonjs-3/),他在開頭介紹了這一點。他的一個例子實際上讓我發佈了這個問題。謝謝! – weisjohn

+2

正如您在免責聲明中所說的,您對「聲明」和「表達」的使用有點混淆。你最後的兩個函數「聲明」真的是表達式。 'var a = ...'語法意思是「聲明變量'a'並將其賦值爲引用右側的函數表達式」。我不確定not(!)語法。 – nnnnnn