“提升”以及函數(shù)聲明和函數(shù)表達(dá)式

一. 函數(shù)聲明

// 函數(shù)聲明
function funDeclaration(type){ return type==="Declaration"; }

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

// 函數(shù)表達(dá)式
var funExpression = function(type){ return type==="Expression"; }
 
用函數(shù)聲明創(chuàng)建的函數(shù)funDeclaration可以在funDeclaration定義之前就進(jìn)行調(diào)用;而用函數(shù)表達(dá)式創(chuàng)建的funExpression函數(shù)不能在funExpression被賦值之前進(jìn)行調(diào)用。
為什么會這樣呢?!這就要理解Javascript Function兩種類型的區(qū)別:用函數(shù)聲明創(chuàng)建的函數(shù)可以在函數(shù)解析后調(diào)用(解析時進(jìn)行等邏輯處理);而用函數(shù)表達(dá)式創(chuàng)建的函數(shù)是在運(yùn)行時進(jìn)行賦值,且要等到表達(dá)式賦值完成后才能調(diào)用。
這個區(qū)別看似微小,但在某些情況下確實(shí)是一個難以發(fā)現(xiàn)的陷阱。出現(xiàn)這個陷阱的本質(zhì)原因體現(xiàn)在這兩種類型在Javascript function hoisting(函數(shù)提升)和運(yùn)行時機(jī)(解析時/運(yùn)行時)上的差異

三. 提升

誰會被提升

變量聲明:使用var ,let ,const關(guān)鍵字
函數(shù)聲明:使用function(){......}語法
類聲明:使用class關(guān)鍵字

  1. 函數(shù)聲明在函數(shù)作用域內(nèi)創(chuàng)建并初始化一個變量。默認(rèn)情況下,聲明但是未初始化的變量的值是undefined。
  2. javascript并沒有嚴(yán)格遵循這個順序,因此提供了更多的靈活性。比如:函數(shù)的使用可以在聲明之前。(目前就這個)
var foo;
function foo(){
    console.log(1);
}

foo = function(){
    console.log(2);
}```

會輸出1二不是2!這個代碼片段會被引擎理解為如下形式:

function foo(){
console.log(1);
}
foo();//1
foo = function(){
console.log(1);
}
foo();//1


注意:var foo盡管出現(xiàn)在 function foo()...的聲明之前,但它是重復(fù)的聲明(因此被忽略了),因?yàn)楹瘮?shù)聲明會被提升到普通變量之前。

盡管**重復(fù)的var** 聲明會被忽略掉,但出現(xiàn)在后面的函數(shù)聲明還是可以**覆蓋**前面的。

##四. 總結(jié)
無論作用域中的聲明出現(xiàn)在什么地方,都將在代碼本身被執(zhí)行前首先進(jìn)行處理??梢詫⑦@個過程形象地想象成所有的聲明(變量和函數(shù))都會被“移動”到各自作用域的最頂端,這個過程被稱為提升。

聲明本身會被提升,而包括函數(shù)表達(dá)式的賦值在內(nèi)的賦值操作并不會提升。要注意避免重復(fù)聲明,特別是當(dāng)普通的var 聲明和函數(shù)聲明混合在一起的時候,否則會引起很多危險(xiǎn)的問題!

**參考至《你不知道的Javascript 上卷》**
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容