js 函數定義和函數表達式的區別

Javascript中有2個語法都與function關鍵字有關,分別是:javascript

函數定義:function FunctionName(FormalParameterList) { FunctionBody }java

函數表達式:function [FunctionName](FormalParameterList) { FunctionBody }算法

從語法的定義上看,這二者幾乎是如出一轍的(惟一的區別是函數表達式能夠省略函數名稱),那麼就解釋器而言,當遇到這個結構的語句時,斷定爲函數表達式仍是函數定義呢?app

就javascript的語法而言,若是一條語句是以function關鍵字開始,那麼這段會被斷定爲函數定義。而函數定義是不能被當即執行的,這無疑會致使語法的錯誤(SyntaxError),所以就必須有一個辦法,使解析器能夠將之識別爲函數表達式。函數

前面已經說到,解析器識別函數定義的條件是以function關鍵字開始,那麼天然,只要在function關鍵字的前面有任何其餘的元素,就會從函數定義轉變爲函數表達式,如下方法都是能夠的,這個你們都知道:lua

~function() {}();spa

!function() {}();orm

void function() {}();ip

可是這幾個方法都有一個特色,就是看起來很彆扭,因此如今爲止,以括號包裹成了比較公認的方案ci

回到正題,括號包裹一樣有2個方式:(function() {})();和(function(){}());

他們的共通點是:都有括號。而括號在javascript中有2種做用:確立運算優先級,以及分組運算符,從代碼上看,顯然沒有進行數學或邏輯運算,所以我認爲這裏的括號屬於分組運算符。

根據標準,分組運算符的做用是:

Return the result of evaluating Expression. This may be of type Reference. 

返回評估括號中的表達式的結果。結果多是Reference類型。

拋開像Reference類型這種詞彙,這裏的一個關鍵詞應當是「 評估 」,可是關於分組運算符,又有一個很重要的下文:

This algorithm does not apply GetValue to the result of evaluating Expression.

這個算法不會對估算的結果使用GetValue。

有不少專用的名詞,看起來確實複雜,簡而言之,使用括號運算符自己不會讓括號中的代碼當即執行,只有當括號包含的這個「分組」參與其餘運算時,纔會執行。所以,(function(){})()這個語句,實際上是首先用分組運算符評估了一個函數表達式,隨後參與「函數調用」。而(function(){}())這個語句,則是用分組運算符評估了一個函數調用,隨後因爲語句的結束而被執行。

相關文章
相關標籤/搜索