函數(shù)對于我們這些程序員來說,在熟悉不過啦,我們幾乎每天能在寫函數(shù),使用函數(shù)。可是,在javascript中,大家知道幾種函數(shù)調(diào)用的語句呢?在工作中,常用到的函數(shù)調(diào)用的語句就一兩 個。那為啥大家知道我還在這里寫博客,沒事消磨大家的時間。想要知道,請耐心看完,你就明白啦。
javascript中的函數(shù)本身是一個變量/值,因此函數(shù)調(diào)用其實是一個表達式,如圖1
所以,下面代碼就是函數(shù)調(diào)用語句,它也是一個表達式語句:
functionName();
在javascript中具名函數(shù)可以使用上面方法直接調(diào)用,匿名函數(shù)可以通過引用變量調(diào)用,如果沒有引用的匿名函數(shù)怎么調(diào)用呢?下面的例子說明這三種情況:
// 實例1:具名函數(shù)直接調(diào)用function fnName() { // 函數(shù)體} fnName();// 實例2:匿名函數(shù)通過引用變量調(diào)用var fnName = function () { // 函數(shù)體}; fnName();// 實例3:沒有引用的匿名函數(shù)的調(diào)用(1)(function () { // 函數(shù)體}());// 實例4:沒有引用的匿名函數(shù)的調(diào)用(2)(function () { // 函數(shù)體})();// 實例5:沒有引用的匿名函數(shù)的調(diào)用(3)void function () { // 函數(shù)體}();
實例1,2的用法比較常見,實例4在現(xiàn)在很多的框架中使用的也比較多,實例3,5見的就比較少,但是各有其用。
實例3,4都用于“調(diào)用函數(shù)并返回值”,這兩種表達式有是那個括號,但是意義各不同。如圖2,實例3的說明:
實例4的說明:
其實實例3,4基本是一致。但是它們的運算過程還是有不同:實例3是用強制運算符使函數(shù)調(diào)用運算得以執(zhí)行,實例4則是用強制運算符運算“函數(shù)直接量聲明”這個表達式,并返回一個函數(shù) 自身引用,然后通過函數(shù)調(diào)用運算符“()”,來操作這個函數(shù)的引用。
ps:“函數(shù)調(diào)用運算符()”在實例3中作用于匿名函數(shù)本身,而實例4中卻是作用于一個運算的結(jié)果值。
最后的實例5,則用于“調(diào)用函數(shù)并忽略返回值”。運算符void用于使其后的函數(shù)表達式執(zhí)行運算。然而由此帶來的問題:如果不使用void和()這兩個運算符,而直接使用下面的代碼,是否能 使函數(shù)表達式執(zhí)行呢?
// 實例6:直接使用調(diào)用函數(shù)運算符"()"function () { // 函數(shù)體}()// 實例7:使用語句結(jié)束符";"來執(zhí)行語句function () { // 函數(shù)體}();
實例6,7看起來是right,但是事實上它們都不可以執(zhí)行,原因是它們無法通過腳本引擎的語法檢測。在語法檢測階段,腳本引擎會認為下面的代碼:
function () { // 函數(shù)體}// 或function fnName () { // 函數(shù)體}
結(jié)果是函數(shù)聲明,因此實例6,7中使用具名函數(shù)也是通不過語法檢測的,正因為這里是函數(shù)聲明,所有實例6,7的代碼位于函數(shù)后面的“()”沒有語法意義,它們的代碼被解析成了
// 實例6:語法解釋function () { // 函數(shù)體}; ();// 實例7:同上
既然“function () {}”被當作完整的語法結(jié)構(gòu)(函數(shù)聲明語句)來解釋,那么也就相當于已經(jīng)存在語句結(jié)束符。因此“();”被當作一個語句表達式解釋,而這樣是錯誤的語法。所以,我們 能看到語法錯誤。
如此,這個語法錯誤是針對“();”,不是針對前面的函數(shù)聲明的,下面代碼稍作修改:
// 實例6:通過語法解釋function () { // 函數(shù)體}(1,2)
這樣就通過語法的解釋, 因為語句被語法解釋成了。
// 實例6:直接使用調(diào)用函數(shù)運算符"()"function () { // 函數(shù)體}; (1,2);
圖4,被解釋成了兩個單值表達式,,也可以是單個單值表達式。但是這重要的是,這代碼被解釋成了一函數(shù)直接量聲明和一個表達式語句,因此它不能起到“執(zhí)行函數(shù)并傳入?yún)?shù)”的作用。如果你真的想在聲明的時候執(zhí)行一下該函數(shù),那么可以參考實例3,4,5,用“()”或void運算符將函數(shù)聲明變成“單值表達式”
void function () { // 函數(shù)體}(1,2);
當引擎在解釋這樣的代碼時,由于先識別到運算符void,于是將后面的匿名函數(shù)識別為操作數(shù)。
上述就javascript中的函數(shù)調(diào)用語句,說實在的最后那個我也是看到書本上的,但是,我還是一直沒太明白,如果那位高手可以指點其中的原委那就太感謝啦。也希望這個能幫到其他剛學習javascript的同學們。