轉載:https://www.cnblogs.com/tu-0718/p/9584184.html

可能光這樣看,有些小伙伴會有些蒙蔽,不知道到底有什么區別?
請大家先看下面的代碼:
<script>
y();
function y() {
alert(2);
};
x();
var x = function() {
alert(1);
};
</script>
上面的代碼運行以后,會先執行y()方法,並彈出2;然后在執行x()方法,但這里會報錯:x is not a function
為什么會是這樣的呢? 這就是函數定義2種方法的不同造成的。
上述y(),也就是定義函數的第一種方法 (官方稱為-聲明式定義函數)
大家知道JS變量是有變量聲明提前的,其實函數也是有函數名聲明提前的。
(另外,函數內部用var聲明的局部變量也會把聲明提前到函數代碼頂部)
瀏覽器是從上到下開始解析,但因函數名聲明提前(當沒有解析到該方法代碼之前,會自動提升到代碼頂部,固能全局調用該方法)
盡管這個時候還沒有解析到y()方法的代碼,依然可以先調用該方法。所以y()方法會順利執行,也不會報錯。
上述x(),也就是定義函數的第二種方法(官方稱為-函數表達式):
而x()方法則會報錯提示:x is not a function, 因為第二種函數定義的寫法,不會讓函數名聲明提前。
所以,瀏覽器從上往下執行,要先執行x()方法的代碼,然后才能調用,比如下面這樣就不會報錯
var x = function() {
alert(1);
};
x();
推薦第二種方式定義函數
注:函數表達式需要在語句的結尾加上分號,表示語句結束。而聲明式定義函數在結尾的大括號后面不用加分號
補充:還有一種函數寫法,官方稱為(立即執行函數);
有 3 種 寫法(推薦第一或第二種):
(function(){
alert(1);
})();
(function(){
alert(2);
}());
!function(){
alert(3);
}();

