function foo(){}、(function(){})、(function(){}())等函數區別分析


  前面一段時間,看到(function(){}),(function(){}())這些函數就犯暈,不知道它到底是什么意思,為什么函數外要加小括號,函數后要加小括號,加和不加到底有什么區別……一直犯迷糊,看了湯姆大叔的《深入理解JavaScript系列(4):立即調用的函數表達式》后才明白它們到底是什么東西,終於將困擾我已久的東西給干掉了。

  在這里,我先介紹一下函數引用和函數調用的差別、函數聲明表現形式和函數表達式的表現形式。

  一、函數引用和函數調用的差別

  函數引用和調用的差別與函數名稱后是否有小括號()有關,函數引用只會單獨出現,但函數調用后面必定會帶有一個小括號,很多時候還附有自變量。

  表示方式(舉例說明):

function foo(){
    //函數體
}
var f = foo;  //函數引用
var ff = foo();  //函數調用,可直接調用foo(),也可調用f()

  二、函數聲明的表現形式

  帶有函數名的函數是函數聲明,包括保留字function,函數名(必有),圓括號中的參數(可有可無)和花括號中的函數主體。

  表示方式(舉例說明):

function foo(str){
    //函數體
}

  三、函數表達式的表現形式

  賦值函數,函數外帶有小括號的函數是函數表達式(就舉兩個例子),包括賦值變量(可有),函數外小括號(可有),保留字function,函數名(可有可無),圓括號中的參數(可有可無)和花括號中的函數主體。

  表示方式(舉例說明):

//賦值型函數表達式
var f = function foo(str){
    //函數體
}
//分組括號型函數表達式,這是立即執行函數表達式,后面會講解
(function(){
    //函數體
})();

  四、函數實例

  第一種:

var foo = function(){}

  分析:該函數為函數表達式,也可以理解成是一個引用,用foo()調用可執行。

  第二種:

var foo = function(){}();

  分析:該函數為立即調用函數,這和第一種的區別就是后面有無小括號,也就是函數調用和函數引用的區別,函數調用可理解為自執行函數(最好在function(){}外加一個括號變成(function(){})(),更規范一點);

  第三種:

function(){}

  分析:該函數缺少名稱,未賦值,所以報錯。

  第四種:

function(){}()

  分析:function(){}是語句,不是函數表達式,只有表達式才能調用,所以報錯。

  第五種:

(function(){})();

  分析:(function(){})是函數表達式,能調用,稱為匿名自執行函數。

  第六種:

(function(){}());

  分析:(function(){}())是函數表達式,可用,稱為匿名自執行函數(湯姆大叔推薦的寫法,我更喜歡第五種寫法)。

  第七種:

function foo(){}

  分析:該函數為實名函數,可調用。

  第八種:

function foo(){}();

  分析:解釋和第四種一樣,因為function foo(){}是語句,不是表達式,不能調用,所以報錯。

  第九種:

function foo(){}(a);

  分析:解釋和第四種一樣,因為function foo(){}是語句,不是表達式,不能調用,但是因為后面括號中傳入了參數,所以未拋出異常,也就為報錯,但是本身還是不執行的。

  第十種:

(function foo(){});

  分析:function外添加一個括號,所以外部作用域就不能調用foo()這個函數了,里面被當做匿名函數了,我個人認為這樣的函數沒什么意義,既不能調用也不能自執行。

  第十一種:

(function foo(){})();

  分析:有了十,這個就可以理解為是匿名自執行函數了。但是在ie8以下能執行,該表達式被當做函數聲明,函數聲明有種“置頂解析”的行為,就是不管函數在哪個地方定義,它都會在該作用域頂部默認聲明好。

  第十二種:

!function(){}();

  分析:其實小括號和js的&&,異或,感嘆號等操作是在函數聲明和表達式消除歧義的,為可執行的。

  第十三種:

new function(){}();

  分析:可執行。

  最后,非常感謝。有哪里講解的不好或者是不正確的地方,希望大家能第一時間反饋給我,希望和大家共同進步~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM