一、js函數分兩種
1)聲明函數:function funcName(){};
2)函數表達式 var add=function(){};
注意:
1、在js解釋器中,如果遇到函數聲明,會自動提升函數聲明,這是函數的一個重要特征,解釋器會優先讀取函數聲明,所以我們在代碼中,可以把函數放在調用語句的后面。而不會報出:xxx is undefined.
1 add(1,2); 2 function add(a,b){ 3 console.log(a+b); 4 }
2、函數表達式,在調用的時候,必須先賦值負責會報錯 undefined。因為函數表達式需要賦值給一個變量才能進行調用。所以沒進行賦值的時候,直接進行調用會出現報錯。
1 add(1,2); 2 var add=function (a,b){ 3 console.log(a+b); 4 }
報錯:Uncaught TypeError: add is not a function。
造成這種現象是因為解析器在向執行環境中加載數據中,解析器會率先讀取函數聲明,並使其在執行任何代碼前可用,至於函數表達式,則必須等到解析器,執行到他的所在的代碼行,才能真正的被解析。函數表達式中,創建的函數叫做匿名函數,function之后無標識符即函數名字。
二、匿名函數的執行方法:
1)變量賦值:直接通過 varName()進行調用。
1 var add=function (a,b){ 2 console.log(a+b); 3 } 4 add(1,2);
2)匿名函數另一種方法調用:使用小括號進行包裹匿名函數,在小括號后面加小括號進行調用。
1 (function (){ 2 console.log(1) 3 })()
這種形式調用,我們經常會看見,尤其在插件中看到, 我們在寫工廠函數的時候結合這種執行方式。
1 var myUtil=( 2 function(){ 3 function add(a,b){ 4 console.log(a+b) 5 }; 6 function isFunction(a){ 7 return a instanceof Function 8 }; 9 function isArray(c){ 10 return c instanceof Array; 11 } 12 return { 13 add:add, 14 isFunction:isFunction, 15 isArray:isArray 16 } 17 } 18 )() 19 myUtil.add(1,2);
這種方式比較好,避免我們定義的函數的被其他作用域污染。
這種執行方式:()() 在解析器讀到這塊代碼的的時候,會執行該函數,所以我們在調用其中的方法的的時候不需要 myUtil() 因為匿名函數已經 執行完並賦值給myUti 直接進行調用即可。
3、自執行函數:
自執行函數,即定義和調用合為一體。我們創建了一個匿名函數,並立即執行它,由於外部無法引用他的內部變量,因此在執行完之后就會被釋放
關鍵這種機制不會污染全局對象。
在我們查看一些編碼和組件的時候會看到一些其他方式的自執行函數:
1)匿名函數后面直接跟小括號也會立即執行。或者直接小括號包裹匿名函數在跟着小括號也是立即執行。
1 (function(){ 2 console.log(2) 3 }())
1 (function(){ 2 console.log(2); 3 })()
2)由於小括號和js的&&、異、逗號等操作符是在函數表達和函數聲明生消除歧義的,所以一旦解析器認為一個是表達式默認另一個認為是表達式。
1 0,function(){ 2 console.log(2) 3 }() 4 || function(){ 5 console.log(22) 6 }() 7 true && function(){ 8 console.log(222) 9 }() 10 var a=function(){ 11 console.log(2222); 12 }()
3)如果不關心返回值以及不易讀也可以在前面加一些一元操作符。
1 +function(){}( 2 console.log(111) 3 ) 4 -function(){ 5 console.log(222); 6 }() 7 % function(){ 8 console.log(333) 9 }()