函式宣告與函式表示式以及立即執行函式的討論
函式宣告的定義:function fn(){……},使用function關鍵字宣告一個函式,再指定一個函式名,叫函式宣告。
函式表示式:var fn=function(){……},使用function關鍵字宣告一個函式,但未給函式命名,最後將匿名函式賦予一個變數,叫函式表示式,這是最常見的函式表示式語法形式。
匿名函式:function(){……},使用function關鍵字宣告一個函式,但未給函式命名,所以叫匿名函式,匿名函式屬於函式表示式,匿名函式有很多作用,賦予一個變數則建立函式,賦予一個事件則成為事件處理程式或建立閉包等等。
函式宣告和函式表示式不同之處在於:一、Javascript引擎在解析javascript程式碼時會‘函式宣告提升'(Function declaration Hoisting)當前執行環境(作用域)上的函式宣告,而函式表示式必須等到Javascirtp引擎執行到它所在行時,才會從上而下一行一行地解析函式表示式,二、函式表示式後面可以加括號立即呼叫該函式,函式宣告不可以,只能以fn()形式呼叫 。以下是兩者差別的兩個例子。
<script type="text/javascript">
fn1();//不會報錯,因為"提升了"函式宣告,函式呼叫可在函式宣告之前
function fn1(){
console.log("這裡是函式宣告");
}
fn2();//會報錯,變數fn2還未儲存對函式的引用,函式呼叫必須在函式表示式之後
var fn2=function(){
console.log("這裡是函式表示式");
}
</script>
關於立即執行函式的討論
下面看經典的立即執行函式樣式<script type="text/javascript"> //情況1 //結果會被輸出 var fn=function(){ console.log("函式表示式賦值給一個變數"); }(); //情況2 //結果不會被輸出,JavaScript引擎只解析函式宣告,忽略後面的括號,函式宣告不會被呼叫 function fn(){ console.log("函式宣告"); }(); //情況3 //語法錯誤,匿名函式屬於函式表示式,未執行賦值操作,不能被呼叫 function(){ console.log("函式表示式"); }(); </script>
<script type="text/javascript"> (function(a){ console.log(a); })(123); (function(a){ console.log(a); }(1234)); !function(a){ console.log(a); }(12345); +function(a){ console.log(a); }(123456); -function(a){ console.log(a); }(1234567); </script>
也就是說只有函式表示式才能實現立即執行,匿名函式也是函式表示式為何不能立即執行呢,因為匿名函式開始的function會被JavaScript引擎識別為函式宣告的開始,所以加上括號也不會被執行了,而加上(),!,+,-等符號為什麼就可以了呢,因為加上這些符號就可以告訴JavaScript引擎這不是函式聲明瞭,就這麼簡單。
目前使用最多的還是加括號的形式,這種形式有什麼好處呢?
(function(){……})()這種形式可以模仿一個作用域容器,在這裡面定義的變數可以不受外界影響,外部無法呼叫也無法因為外部變數重名而覆蓋,起到防止汙染全域性的作用