下面小編就為大家?guī)硪黄獪\析函數(shù)聲明和函數(shù)表達式——函數(shù)聲明的聲明提前。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。
前兩天班級聚會,除了吃喝玩樂就是睡覺扯淡,甚是喜悅,真是獨樂樂不如眾樂樂啊。
PS:畢業(yè)的或即將畢業(yè)的有時間能聚就聚吧,畢了業(yè)以后屬于自己的時間能聚到一塊兒可就少太多了。
現(xiàn)在有點時間來看點東西總結(jié)些東西了,又因為前段時間片片斷斷地看了看JavaScript的函數(shù)部分,所以抽時間總結(jié)下函數(shù)的相關(guān)部分,當然,里面有些部分都是自己的理解,如果有理解的不對的地方還請小伙伴們不吝指出。
這一節(jié)我結(jié)合自己的理解和小伙伴們聊一下函數(shù)聲明的聲明提前。
注:有的地方也叫函數(shù)聲明提升。翻譯的不一樣,意思一樣,大家理解就行。理解萬歲!
在聊函數(shù)聲明的聲明提前之前,有必要介紹下函數(shù)定義的幾種方法,大部分小伙伴們應(yīng)該都不陌生。了解的或者不想了解的就痛快地一滾輪滾下去吧,不熟悉的或者想再熟悉一下的就放慢腳步起步走。
定義函數(shù)的方法
定義函數(shù)的方法主要有三種:
1.函數(shù)聲明(Function Declaration)
2.函數(shù)表達式Function Expression)
3.new Function構(gòu)造函數(shù)
其中,經(jīng)常使用的是函數(shù)聲明和函數(shù)表達式的函數(shù)定義方法,這兩種方法有著很微妙的區(qū)別和聯(lián)系,而且這兩種方法的使用也容易混淆,所以這篇文章主要總結(jié)下這兩種函數(shù)定義方法的相關(guān)知識點,當然本文的主題依然是關(guān)于函數(shù)提前的。
函數(shù)聲明的典型格式:
function functionName(arg1, arg2, ...){
<!-- function body -->
}
函數(shù)表達式
•函數(shù)表達式的典型格式:
var variable=function(arg1, arg2, ...){
<!-- function body -->
}
包含名稱(括弧,函數(shù)名)的函數(shù)表達式:
var variable=function functionName(arg1, arg2, ...){
<!-- function body -->
}
像上面的帶有名稱的函數(shù)表達式可以用來遞歸:
var variable=function functionName(x){
if(x<=1)
return 1;
else
return x*functionName(x);
}
聲明提前
var聲明提前
小伙伴們應(yīng)該都聽說過聲明提前的說法,我想在此再次重申一遍,因為聲明提前是函數(shù)聲明和函數(shù)表達式的一個重要區(qū)別,對于我們進一步理解這兩種函數(shù)定義方法有著重要的意義。
但是再說函數(shù)聲明提前之前呢,有必要說一下var聲明提前。
先給出var聲明提前的結(jié)論:
變量在聲明它們的腳本或函數(shù)中都是有定義的,變量聲明語句會被提前到腳本或函數(shù)的頂部。但是,變量初始化的操作還是在原來var語句的位置執(zhí)行,在聲明語句之前變量的值是undefined。
上面的結(jié)論中可以總結(jié)出三個簡單的點:
1.變量聲明會提前到函數(shù)的頂部;
2.只是聲明被提前,初始化不提前,初始化還在原來初始化的位置進行初始化;
3.在聲明之前變量的值是undefined。
還是來例子實在:
var handsome='handsome';
function handsomeToUgly(){
alert(handsome);
var handsome='ugly';
alert(handsome);
}
handsomeToUgly();
正確的輸出結(jié)果是:
先輸出undefined,然后輸出ugly。
錯誤的輸出結(jié)果是:
先輸出handsome,然后輸出ugly。
這里正是變量聲明提前起到的作用。該handsome局部變量在整個函數(shù)體內(nèi)都是有定義的,在函數(shù)體內(nèi)的handsome變量壓住了,哦不對,是覆蓋住了同名的handsome全局變量,因為變量聲明提前,即var handsome被提前至函數(shù)的頂部,就是這個樣子:
var handsome='handsome';
function handsomeToUgly(){
var handsome;
alert(handsome);
var handsome='ugly';
alert(handsome);
}
handsomeToUgly();
所以說在alert(handsome)之前,已經(jīng)有了var handsome聲明,由上面提到的
在聲明之前變量的值是undefined
所以第一個輸出undefined。
又因為上面提到的:
只是聲明被提前,初始化不提前,初始化還在原來初始化的位置進行初始化
所以第二個輸出ugly。
函數(shù)聲明提前
接下倆我們結(jié)合var聲明提前開始聊函數(shù)聲明的聲明提前。
函數(shù)聲明的聲明提前小伙伴們應(yīng)該很熟悉,舉個再熟悉不過的例子。
sayTruth();<!-- 函數(shù)聲明 -->
function sayTruth(){
alert('myvin is handsome.');
}
sayTruth();<!-- 函數(shù)表達式 -->
var sayTruth=function(){
alert('myvin is handsome.');
}
小伙伴們都知道,對于函數(shù)聲明的函數(shù)定義方法,即上面的第一種函數(shù)調(diào)用方法是正確的,可以輸出myvin is handsome.的真理,因為函數(shù)調(diào)用語句可以放在函數(shù)聲明之后。而對于函數(shù)表達式的函數(shù)定義方法,即上面的第二種函數(shù)調(diào)用的方法是不能輸出myvin is handsome.的正確結(jié)果的。
結(jié)合上面的myvin is handsome.例子,函數(shù)聲明提前的結(jié)論似乎很好理解,不就是在使用函數(shù)聲明的函數(shù)定義方法的時候,函數(shù)調(diào)用可以放在任意位置嘛。對啊,你說的很對啊,小伙伴,我都不知道怎么反駁你了。那就容我再扯幾句。
從小伙伴所說的
不就是在使用函數(shù)聲明的函數(shù)定義方法的時候,函數(shù)調(diào)用可以放在任意位置嘛
可以引出一點:
函數(shù)聲明提前的時候,函數(shù)聲明和函數(shù)體均提前了。
而且:
函數(shù)聲明是在預(yù)執(zhí)行期執(zhí)行的,就是說函數(shù)聲明是在瀏覽器準備執(zhí)行代碼的時候執(zhí)行的。因為函數(shù)聲明在預(yù)執(zhí)行期被執(zhí)行,所以到了執(zhí)行期,函數(shù)聲明就不再執(zhí)行(人家都執(zhí)行過了自然就不再執(zhí)行了)。
上面是一點。
函數(shù)表達式為什么不能聲明提前
我們再說一點:為什么函數(shù)表達式不能像函數(shù)聲明那樣進行函數(shù)聲明提前呢?
辛虧我知道一點兒,否則真不知道我該怎么回答呢?
咳咳,按照我的理解給小伙伴們解釋一下下:
我們上面說了var的聲明提前,注意我上面提過的:
只是聲明被提前,初始化不提前,初始化還在原來初始化的位置進行初始化
Ok,我們把函數(shù)表達式擺在這看看:
var variable=function(arg1, arg2, ...){
<!-- function body -->
}
函數(shù)表達式就是把函數(shù)定義的方式寫成表達式的方式(貌似是白說,但是這對于解釋和理解為毛函數(shù)表達式不能函數(shù)聲明提前具有良好的療效),就是把一個函數(shù)對象賦值給一個變量,所以我們把函數(shù)表達式寫成這個樣子:
var varible=5看到這,也許小伙伴們會明白了,一個是把一個值賦值給一個變量,一個是把函數(shù)對象賦值給一個變量,所以對于函數(shù)表達式,變量賦值是不會提前的,即function(arg1, arg2, ...){<!-- function body -->}是不會提前的,所以函數(shù)定義并沒有被執(zhí)行,所以函數(shù)表達式不能像函數(shù)聲明那樣進行函數(shù)聲明提前。
函數(shù)聲明提前的實例分析
還是那句話,還是例子來的實在:
sayTruth();
if(1){
function sayTruth(){alert('myvin is handsome')};
}
else{
function sayTruth(){alert('myvin is ugly')};
}
在瀏覽器不拋出錯誤的情況下(請自行測試相應(yīng)的瀏覽器是否有拋出錯誤的情況,為啥我不測試?我能說我懶么。。。),瀏覽器的輸出結(jié)果是輸出myvin is ugly(我不愿承認,但是事實就是這樣啊啊啊啊,難道道出了人丑就該多讀書??????)。
為什么呢?當然是聲明提前了。因為函數(shù)聲明提前,所以函數(shù)聲明會在代碼執(zhí)行前進行解析,執(zhí)行順序是這樣的,先解析function sayTruth(){alert('myvin is handsome')},在解析function sayTruth(){alert('myvin is ugly')},覆蓋了前面的函數(shù)聲明,當我們調(diào)用sayTruth()函數(shù)的時候,也就是到了代碼執(zhí)行期間,聲明會被忽略,所以自然會輸出myvin is ugly(好殘酷的現(xiàn)實。。。)。忘了的可以看上面說過的:
函數(shù)聲明是在預(yù)執(zhí)行期執(zhí)行的,就是說函數(shù)聲明是在瀏覽器準備執(zhí)行代碼的時候執(zhí)行的。因為函數(shù)聲明在預(yù)執(zhí)行期被執(zhí)行,所以到了執(zhí)行期,函數(shù)聲明就不再執(zhí)行了(人家都執(zhí)行過了自然就不再執(zhí)行了)。
小了個結(jié)
關(guān)于函數(shù)聲明的函數(shù)提前(提升)就聊到這里先,希望我的理解和扯淡能夠?qū)τ行枰男』锇橛兴鶐椭?/P>
當然,實踐出真知。對事物的了解、認知和運用還是在于多看多用多總結(jié),記得有句名言,是講聲明和實踐的:“動起來,為新的聲明喝彩。”。
以上這篇淺析函數(shù)聲明和函數(shù)表達式——函數(shù)聲明的聲明提前就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考