2012-11-20 111 views
3

我正在從Crockford的書Javascript學習JavaScript:The Good Parts。他在那裏解釋如何使用閉包來封裝信息。例如。定義函數返回對象文字

var myObject = (function() { 
    var value = 0; 
    return { 
     getValue: function() { 
      return value; 
     } 
    }; 
}()); 

如果我正確地理解了這一點,我們的想法是我們定義一個函數返回對象文字。這個函數然後被調用來初始化myObject。但最外括號是什麼?[(f ...);]。對()足以調用我們定義的函數嗎?

+1

查找「IIFE」或「立即調用函數表達式」。不缺重複。選一個。 – 2012-11-20 05:54:17

回答

6

你是對的;最外面的圓括號什麼都不做,儘管無論如何都是通常的做法 - 它有助於提高可讀性。當人們看到這樣一個括號內的函數時,他們期望它立即被調用,而如果括號不在那裏,它可能一開始就不那麼明顯。這只不過是一個視覺提示。需要在某些情況下

然而,需要注意的是圍繞一個括號功能,使之成爲函數表達式而非函數聲明

例如,下面將工作:

function() { 
    // Do something... 
}(); 
// Throws a syntax error. 

在這種情況下,你會因爲解析器期待一個函數聲明出現語法錯誤,而你沒有給這個函數是一個名字。另外,你不能立即調用函數聲明。您需要括號將其轉換成函數表達式

(function() { 
    // Do something... 
})(); 

在函數聲明和函數表達式的區別是一個函數聲明,可以使用同樣的方式來聲明函數爲var可以使用聲明變量:

// Declare the variable foo. 
var foo; 

// Declare the function bar. 
function bar() { 
    // Do something... 
} 

但是,函數表達式並未聲明變量。相反,它只是創建一個函數,您可以將其用於某些內容,例如將其分配給一個變量或僅用於調用。

爲了製作一個函數表達式,你只需要用function以外的其他東西開始行。如上所示,一種常用技術是用括號開始。至於你提到你也可以var something = ...開始行:

var foo = function() { 
    return 5; 
}(); 
// foo is now 5 

你真的可以與任何這將使雖然有效表達其啓動:

!function() { 
    console.log(1); 
}(); 
// logs 1 

~function() { 
    console.log(2); 
}(); 
// logs 2 

+function() { 
    console.log(3); 
}(); 
// logs 3 

[ function() { 
    console.log(4); 
}() ]; 
// logs 4 

'Hello, World' == function() { 
    console.log(5); 
}(); 
// logs 5 

當然,如果你想將函數的結果存儲在變量中,您將無法使用這些模式中的任何一種,因爲它們都與返回值混淆。大多數人堅持使用括號包裝功能,無論它們是否必要,只是爲了一致性和可讀性。

+1

謝謝。一個清楚而好的答案。 – Parzival