溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

JS中函數(shù)聲明與函數(shù)表達(dá)式的異同

發(fā)布時(shí)間:2020-06-23 18:07:51 來源:網(wǎng)絡(luò) 閱讀:274 作者:蓓蕾心晴 欄目:開發(fā)技術(shù)

相同點(diǎn)

注:函數(shù)聲明和函數(shù)表達(dá)式的相同點(diǎn)包括但不限于以下幾點(diǎn)

  1. 函數(shù)是一個(gè)值,所以和其他值一樣,函數(shù)也可以進(jìn)行被輸出、被賦值、作為參數(shù)傳給其他函數(shù)等相關(guān)操作,不管函數(shù)是以什么方式被定義的,當(dāng)然和其他值的輸出還是有些區(qū)別的。

    我們先來輸出這個(gè)值:

    function nameAlert(name){
        alert('博主的名字是:' + name + ' 。');
    }
    alert(nameAlert);
    注意輸出的結(jié)果并不是1,而是這個(gè)函數(shù)的整個(gè)源代碼,即輸出結(jié)果為:function nameAlert(name){
        alert('博主的名字是:' + name + ' 。');
    }
  2. 作為參數(shù)傳給其他函數(shù)。

    function nameAlert(name){
        alert('博主的名字是:' + name + ' 。');
    }var anotherNameAlert=nameAlert;
    anotherNameAlert('myvin');

    該例子中將函數(shù)nameAlert作為參數(shù)傳給了anotherNameAlert,然后anotherNameAlert也指向了該函數(shù)。

    這里就涉及到了函數(shù)的傳遞,函數(shù)的傳遞是傳引用,就是說函數(shù)存在內(nèi)存中的某個(gè)位置,nameAlertanotherNameAlert是都是函數(shù)的一個(gè)引用,把函數(shù)名nameAlert賦值給anotherNameAlert的時(shí)候,它們引用的都是同一個(gè)函數(shù)。

    所以anotherNameAlert的輸出結(jié)果為:

    博主的名字是:myvin 。

當(dāng)然函數(shù)還有其他特點(diǎn),在此不再介紹,感興趣的可以自己總結(jié)下。

不同點(diǎn)

注:函數(shù)聲明和函數(shù)表達(dá)式的不同點(diǎn)包括但不限于以下幾點(diǎn)

相對函數(shù)聲明和函數(shù)表達(dá)式之間的相同點(diǎn),它們的不同點(diǎn)更應(yīng)該值得我們關(guān)注。下面我結(jié)合自己的理解聊聊。

  1. 函數(shù)聲明必須有標(biāo)識符,也就是常說的函數(shù)名;函數(shù)表達(dá)式可以省略函數(shù)名。

    關(guān)于它們的定義的不同小伙伴們應(yīng)該都知道,我們簡單重復(fù)一遍。

    如下:

    函數(shù)聲明(要帶標(biāo)識符)

    function functionName(arg1, arg2, ...){    <!-- function body -->}

    函數(shù)表達(dá)式

  • 省略標(biāo)識符

    var  variable=function(arg1, arg2, ...){        <!-- function body -->}
  • 帶有標(biāo)識符

    var  variable=function functionName(arg1, arg2, ...){        <!-- function body -->}
函數(shù)聲明會提前函數(shù)聲明是在預(yù)執(zhí)行期執(zhí)行的,就是說函數(shù)聲明是在瀏覽器準(zhǔn)備執(zhí)行代碼的時(shí)候執(zhí)行的。因?yàn)楹瘮?shù)聲明在預(yù)執(zhí)行期被執(zhí)行,所以到了執(zhí)行期,函數(shù)聲明就不再執(zhí)行(人家都執(zhí)行過了自然就不再執(zhí)行了)。例子的話還是前文的說真話函數(shù):sayTruth();<!-- 函數(shù)聲明 -->function sayTruth(){     alert('myvin is handsome.'); } sayTruth();<!-- 函數(shù)表達(dá)式 -->var sayTruth=function(){     alert('myvin is handsome.'); }即函數(shù)聲明的話sayTruth()可以提前調(diào)用,就是不請自來的那種,而函數(shù)表達(dá)式是什么時(shí)候遇到什么時(shí)候執(zhí)行。函數(shù)聲明提前是它們很大的一個(gè)不同點(diǎn),理解這一點(diǎn)對于我們函數(shù)的應(yīng)用有很大幫助,能使我們避免一些錯誤。ECMAScript規(guī)范中表示,函數(shù)聲明語句可以出現(xiàn)在全局代碼中,或者內(nèi)嵌在其他函數(shù)中,但是不能出現(xiàn)在循環(huán)、條件判、或者try/finally以及with語句中。對于這條,可能會有所疑問:“上文不是有一個(gè)函數(shù)聲明出現(xiàn)在if循環(huán)中的么”。的確是這樣,但是規(guī)定下發(fā)了,遵守不遵守就是另一回事了。JavaScript對于這條規(guī)范的實(shí)現(xiàn)并不是嚴(yán)格遵守的,F(xiàn)F中允許if中出現(xiàn)函數(shù)聲明。但不管規(guī)范怎么樣,造成這樣的原因還是函數(shù)聲明提前。還是引用上文的例子和說明:sayTruth();  if(1){function sayTruth(){alert('myvin is handsome')}; }else{function sayTruth(){alert('myvin is ugly')}; }為什么呢?當(dāng)然是聲明提前了。因?yàn)楹瘮?shù)聲明提前,所以函數(shù)聲明會在代碼執(zhí)行前進(jìn)行解析,執(zhí)行順序是這樣的,先解析function sayTruth(){alert('myvin is handsome')},在解析function sayTruth(){alert('myvin is ugly')},覆蓋了前面的函數(shù)聲明,當(dāng)我們調(diào)用sayTruth()函數(shù)的時(shí)候,也就是到了代碼執(zhí)行期間,聲明會被忽略,所以自然會輸出myvin is ugly??梢詣?chuàng)建一個(gè)函數(shù)表達(dá)式即刻執(zhí)行。(function(){ alert('博主的名字是:myvin 。'); })()這樣可以使得全局變量不受局部變量的影響,保持全局的干凈。注意,括號里面的是表達(dá)式。

事實(shí)上,js的解析器對函數(shù)聲明與函數(shù)表達(dá)式并不是一視同仁地對待的。對于函數(shù)聲明,js解析器會優(yōu)先讀取,確保在所有代碼執(zhí)行之前聲明已經(jīng)被解析,而函數(shù)表達(dá)式,如同定義其它基本類型的變量一樣,只在執(zhí)行到某一句時(shí)也會對其進(jìn)行解析,所以在實(shí)際中,它們還是會有差異的,具體表現(xiàn)在,當(dāng)使用函數(shù)聲明的形式來定義函數(shù)時(shí),可將調(diào)用語句寫在函數(shù)聲明之前,而后者,這樣做的話會報(bào)錯。


參考鏈接:http://www.cnblogs.com/myvin/p/4649789.html

http://blog.csdn.net/one_and_only4711/article/details/6361131


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI