// 函數聲明 function wscat(type){ return type==="wscat"; }
// 函數表達式 var oaoafly = function(type){ return type==="oaoafly"; }
先看下面這個經典問題,在一個程序裏面同時用函數聲明和函數表達式定義一個名爲getName的函數函數
getName()//oaoafly var getName = function() { console.log('wscat') } getName()//wscat function getName() { console.log('oaoafly') } getName()//wscat
上面的代碼看起來很相似,感受也沒什麼太大差異。但實際上,Javascript函數上的一個「陷阱」就體如今Javascript兩種類型的函數定義上。code
JavaScript 解釋器中存在一種變量聲明被提高的機制,也就是說函數聲明會被提高到做用域的最前面,即便寫代碼的時候是寫在最後面,也仍是會被提高至最前面。
而用函數表達式建立的函數是在運行時進行賦值,且要等到表達式賦值完成後才能調用
var getName//變量被提高,此時爲undefined getName()//oaoafly 函數被提高 這裏受函數聲明的影響,雖然函數聲明在最後能夠被提高到最前面了 var getName = function() { console.log('wscat') }//函數表達式此時纔開始覆蓋函數聲明的定義 getName()//wscat function getName() { console.log('oaoafly') } getName()//wscat 這裏就執行了函數表達式的值
因此能夠分解爲這兩個簡單的問題來看清楚區別的本質ip
var getName; console.log(getName)//undefined getName()//Uncaught TypeError: getName is not a function var getName = function() { console.log('wscat') } var getName; console.log(getName)//function getName() {console.log('oaoafly')} getName()//oaoafly function getName() { console.log('oaoafly') }
這個區別看似微不足道,但在某些狀況下確實是一個難以察覺而且「致命「的陷阱。出現這個陷阱的本質緣由體如今這兩種類型在函數提高和運行時機(解析時/運行時)上的差別。 固然咱們最後要給一個總結:Javascript中函數聲明和函數表達式是存在區別的,函數聲明在JS解析時進行函數提高,所以在同一個做用域內,無論函數聲明在哪裏定義,該函數均可以進行調用。而函數表達式的值是在JS運行時肯定,而且在表達式賦值完成後,該函數才能調用。這個微小的區別,可能會致使JS代碼出現意想不到的bug,讓你陷入莫名的陷阱中。