淺析函數(shù)聲明和函數(shù)表達(dá)式-函數(shù)聲明的聲明提前
來(lái)源:易賢網(wǎng) 閱讀:658 次 日期:2016-07-06 10:35:04
溫馨提示:易賢網(wǎng)小編為您整理了“淺析函數(shù)聲明和函數(shù)表達(dá)式-函數(shù)聲明的聲明提前”,方便廣大網(wǎng)友查閱!

下面小編就為大家?guī)?lái)一篇淺析函數(shù)聲明和函數(shù)表達(dá)式——函數(shù)聲明的聲明提前。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。

前兩天班級(jí)聚會(huì),除了吃喝玩樂(lè)就是睡覺(jué)扯淡,甚是喜悅,真是獨(dú)樂(lè)樂(lè)不如眾樂(lè)樂(lè)啊。

PS:畢業(yè)的或即將畢業(yè)的有時(shí)間能聚就聚吧,畢了業(yè)以后屬于自己的時(shí)間能聚到一塊兒可就少太多了。

現(xiàn)在有點(diǎn)時(shí)間來(lái)看點(diǎn)東西總結(jié)些東西了,又因?yàn)榍岸螘r(shí)間片片斷斷地看了看JavaScript的函數(shù)部分,所以抽時(shí)間總結(jié)下函數(shù)的相關(guān)部分,當(dāng)然,里面有些部分都是自己的理解,如果有理解的不對(duì)的地方還請(qǐng)小伙伴們不吝指出。

這一節(jié)我結(jié)合自己的理解和小伙伴們聊一下函數(shù)聲明的聲明提前。

注:有的地方也叫函數(shù)聲明提升。翻譯的不一樣,意思一樣,大家理解就行。理解萬(wàn)歲!

在聊函數(shù)聲明的聲明提前之前,有必要介紹下函數(shù)定義的幾種方法,大部分小伙伴們應(yīng)該都不陌生。了解的或者不想了解的就痛快地一滾輪滾下去吧,不熟悉的或者想再熟悉一下的就放慢腳步起步走。

定義函數(shù)的方法

定義函數(shù)的方法主要有三種:

1.函數(shù)聲明(Function Declaration)

2.函數(shù)表達(dá)式Function Expression)

3.new Function構(gòu)造函數(shù)

其中,經(jīng)常使用的是函數(shù)聲明和函數(shù)表達(dá)式的函數(shù)定義方法,這兩種方法有著很微妙的區(qū)別和聯(lián)系,而且這兩種方法的使用也容易混淆,所以這篇文章主要總結(jié)下這兩種函數(shù)定義方法的相關(guān)知識(shí)點(diǎn),當(dāng)然本文的主題依然是關(guān)于函數(shù)提前的。

函數(shù)聲明的典型格式:

function functionName(arg1, arg2, ...){

  <!-- function body -->

}

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

•函數(shù)表達(dá)式的典型格式:

var variable=function(arg1, arg2, ...){

      <!-- function body -->

}

包含名稱(chēng)(括弧,函數(shù)名)的函數(shù)表達(dá)式:

var variable=function functionName(arg1, arg2, ...){

    <!-- function body -->

}

像上面的帶有名稱(chēng)的函數(shù)表達(dá)式可以用來(lái)遞歸:

var variable=function functionName(x){

    if(x<=1)

      return 1;

    else

      return x*functionName(x);

}

聲明提前

var聲明提前

小伙伴們應(yīng)該都聽(tīng)說(shuō)過(guò)聲明提前的說(shuō)法,我想在此再次重申一遍,因?yàn)槁暶魈崆笆呛瘮?shù)聲明和函數(shù)表達(dá)式的一個(gè)重要區(qū)別,對(duì)于我們進(jìn)一步理解這兩種函數(shù)定義方法有著重要的意義。

但是再說(shuō)函數(shù)聲明提前之前呢,有必要說(shuō)一下var聲明提前。

先給出var聲明提前的結(jié)論:

變量在聲明它們的腳本或函數(shù)中都是有定義的,變量聲明語(yǔ)句會(huì)被提前到腳本或函數(shù)的頂部。但是,變量初始化的操作還是在原來(lái)var語(yǔ)句的位置執(zhí)行,在聲明語(yǔ)句之前變量的值是undefined。

上面的結(jié)論中可以總結(jié)出三個(gè)簡(jiǎn)單的點(diǎn):

1.變量聲明會(huì)提前到函數(shù)的頂部;

2.只是聲明被提前,初始化不提前,初始化還在原來(lái)初始化的位置進(jìn)行初始化;

3.在聲明之前變量的值是undefined。

還是來(lái)例子實(shí)在:

var handsome='handsome';

function handsomeToUgly(){

  alert(handsome);

  var handsome='ugly';

  alert(handsome);

}

handsomeToUgly();

正確的輸出結(jié)果是:

先輸出undefined,然后輸出ugly。

錯(cuò)誤的輸出結(jié)果是:

先輸出handsome,然后輸出ugly。

這里正是變量聲明提前起到的作用。該handsome局部變量在整個(gè)函數(shù)體內(nèi)都是有定義的,在函數(shù)體內(nèi)的handsome變量壓住了,哦不對(duì),是覆蓋住了同名的handsome全局變量,因?yàn)樽兞柯暶魈崆?,即var handsome被提前至函數(shù)的頂部,就是這個(gè)樣子:

var handsome='handsome';

function handsomeToUgly(){

  var handsome;

  alert(handsome);

  var handsome='ugly';

  alert(handsome);

}

handsomeToUgly();

所以說(shuō)在alert(handsome)之前,已經(jīng)有了var handsome聲明,由上面提到的

在聲明之前變量的值是undefined

所以第一個(gè)輸出undefined。

又因?yàn)樯厦嫣岬降模?/P>

只是聲明被提前,初始化不提前,初始化還在原來(lái)初始化的位置進(jìn)行初始化

所以第二個(gè)輸出ugly。

函數(shù)聲明提前

接下倆我們結(jié)合var聲明提前開(kāi)始聊函數(shù)聲明的聲明提前。

函數(shù)聲明的聲明提前小伙伴們應(yīng)該很熟悉,舉個(gè)再熟悉不過(guò)的例子。

sayTruth();<!-- 函數(shù)聲明 -->

function sayTruth(){

  alert('myvin is handsome.');

}

sayTruth();<!-- 函數(shù)表達(dá)式 -->

var sayTruth=function(){

  alert('myvin is handsome.');

}

小伙伴們都知道,對(duì)于函數(shù)聲明的函數(shù)定義方法,即上面的第一種函數(shù)調(diào)用方法是正確的,可以輸出myvin is handsome.的真理,因?yàn)楹瘮?shù)調(diào)用語(yǔ)句可以放在函數(shù)聲明之后。而對(duì)于函數(shù)表達(dá)式的函數(shù)定義方法,即上面的第二種函數(shù)調(diào)用的方法是不能輸出myvin is handsome.的正確結(jié)果的。

結(jié)合上面的myvin is handsome.例子,函數(shù)聲明提前的結(jié)論似乎很好理解,不就是在使用函數(shù)聲明的函數(shù)定義方法的時(shí)候,函數(shù)調(diào)用可以放在任意位置嘛。對(duì)啊,你說(shuō)的很對(duì)啊,小伙伴,我都不知道怎么反駁你了。那就容我再扯幾句。

從小伙伴所說(shuō)的

不就是在使用函數(shù)聲明的函數(shù)定義方法的時(shí)候,函數(shù)調(diào)用可以放在任意位置嘛

可以引出一點(diǎn):

函數(shù)聲明提前的時(shí)候,函數(shù)聲明和函數(shù)體均提前了。

而且:

函數(shù)聲明是在預(yù)執(zhí)行期執(zhí)行的,就是說(shuō)函數(shù)聲明是在瀏覽器準(zhǔn)備執(zhí)行代碼的時(shí)候執(zhí)行的。因?yàn)楹瘮?shù)聲明在預(yù)執(zhí)行期被執(zhí)行,所以到了執(zhí)行期,函數(shù)聲明就不再執(zhí)行(人家都執(zhí)行過(guò)了自然就不再執(zhí)行了)。

上面是一點(diǎn)。

函數(shù)表達(dá)式為什么不能聲明提前

我們?cè)僬f(shuō)一點(diǎn):為什么函數(shù)表達(dá)式不能像函數(shù)聲明那樣進(jìn)行函數(shù)聲明提前呢?

辛虧我知道一點(diǎn)兒,否則真不知道我該怎么回答呢?

咳咳,按照我的理解給小伙伴們解釋一下下:

我們上面說(shuō)了var的聲明提前,注意我上面提過(guò)的:

只是聲明被提前,初始化不提前,初始化還在原來(lái)初始化的位置進(jìn)行初始化

Ok,我們把函數(shù)表達(dá)式擺在這看看:

var variable=function(arg1, arg2, ...){

          <!-- function body -->

}

函數(shù)表達(dá)式就是把函數(shù)定義的方式寫(xiě)成表達(dá)式的方式(貌似是白說(shuō),但是這對(duì)于解釋和理解為毛函數(shù)表達(dá)式不能函數(shù)聲明提前具有良好的療效),就是把一個(gè)函數(shù)對(duì)象賦值給一個(gè)變量,所以我們把函數(shù)表達(dá)式寫(xiě)成這個(gè)樣子:

var varible=5看到這,也許小伙伴們會(huì)明白了,一個(gè)是把一個(gè)值賦值給一個(gè)變量,一個(gè)是把函數(shù)對(duì)象賦值給一個(gè)變量,所以對(duì)于函數(shù)表達(dá)式,變量賦值是不會(huì)提前的,即function(arg1, arg2, ...){<!-- function body -->}是不會(huì)提前的,所以函數(shù)定義并沒(méi)有被執(zhí)行,所以函數(shù)表達(dá)式不能像函數(shù)聲明那樣進(jìn)行函數(shù)聲明提前。

函數(shù)聲明提前的實(shí)例分析

還是那句話(huà),還是例子來(lái)的實(shí)在:

sayTruth();

if(1){

  function sayTruth(){alert('myvin is handsome')};

}

else{

  function sayTruth(){alert('myvin is ugly')};

}

在瀏覽器不拋出錯(cuò)誤的情況下(請(qǐng)自行測(cè)試相應(yīng)的瀏覽器是否有拋出錯(cuò)誤的情況,為啥我不測(cè)試?我能說(shuō)我懶么。。。),瀏覽器的輸出結(jié)果是輸出myvin is ugly(我不愿承認(rèn),但是事實(shí)就是這樣啊啊啊啊,難道道出了人丑就該多讀書(shū)??????)。

為什么呢?當(dāng)然是聲明提前了。因?yàn)楹瘮?shù)聲明提前,所以函數(shù)聲明會(huì)在代碼執(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í)行期間,聲明會(huì)被忽略,所以自然會(huì)輸出myvin is ugly(好殘酷的現(xiàn)實(shí)。。。)。忘了的可以看上面說(shuō)過(guò)的:

函數(shù)聲明是在預(yù)執(zhí)行期執(zhí)行的,就是說(shuō)函數(shù)聲明是在瀏覽器準(zhǔn)備執(zhí)行代碼的時(shí)候執(zhí)行的。因?yàn)楹瘮?shù)聲明在預(yù)執(zhí)行期被執(zhí)行,所以到了執(zhí)行期,函數(shù)聲明就不再執(zhí)行了(人家都執(zhí)行過(guò)了自然就不再執(zhí)行了)。

小了個(gè)結(jié)

關(guān)于函數(shù)聲明的函數(shù)提前(提升)就聊到這里先,希望我的理解和扯淡能夠?qū)τ行枰男』锇橛兴鶐椭?/P>

當(dāng)然,實(shí)踐出真知。對(duì)事物的了解、認(rèn)知和運(yùn)用還是在于多看多用多總結(jié),記得有句名言,是講聲明和實(shí)踐的:“動(dòng)起來(lái),為新的聲明喝彩?!?。

以上這篇淺析函數(shù)聲明和函數(shù)表達(dá)式——函數(shù)聲明的聲明提前就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考

更多信息請(qǐng)查看網(wǎng)絡(luò)編程
由于各方面情況的不斷調(diào)整與變化,易賢網(wǎng)提供的所有考試信息和咨詢(xún)回復(fù)僅供參考,敬請(qǐng)考生以權(quán)威部門(mén)公布的正式信息和咨詢(xún)?yōu)闇?zhǔn)!

2025國(guó)考·省考課程試聽(tīng)報(bào)名

  • 報(bào)班類(lèi)型
  • 姓名
  • 手機(jī)號(hào)
  • 驗(yàn)證碼
關(guān)于我們 | 聯(lián)系我們 | 人才招聘 | 網(wǎng)站聲明 | 網(wǎng)站幫助 | 非正式的簡(jiǎn)要咨詢(xún) | 簡(jiǎn)要咨詢(xún)須知 | 新媒體/短視頻平臺(tái) | 手機(jī)站點(diǎn) | 投訴建議
工業(yè)和信息化部備案號(hào):滇ICP備2023014141號(hào)-1 云南省教育廳備案號(hào):云教ICP備0901021 滇公網(wǎng)安備53010202001879號(hào) 人力資源服務(wù)許可證:(云)人服證字(2023)第0102001523號(hào)
云南網(wǎng)警備案專(zhuān)用圖標(biāo)
聯(lián)系電話(huà):0871-65099533/13759567129 獲取招聘考試信息及咨詢(xún)關(guān)注公眾號(hào):hfpxwx
咨詢(xún)QQ:1093837350(9:00—18:00)版權(quán)所有:易賢網(wǎng)
云南網(wǎng)警報(bào)警專(zhuān)用圖標(biāo)