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