1.函數聲明javascript
函數聲明以function關鍵字開頭,接着是必須的函數(變量)名和以逗號分隔的可選的參數列表,再接着就是以大括號封裝的函數體。函數聲明必須是一個單獨的JavaScript語句。java
基本語法:函數
function funName(arg1,arg2){ //... }
另外,須要注意的是,函數在運行時全部聲明變量或聲明函數都會被提高到當前函數的頂部。
例以下代碼:spa
console.log('m' in window);//true
var m = 0;
代碼執行時js引擎會將聲明語句提高至代碼最上方,變爲:code
var m; console.log('m' in window);//true m = 0;
2.函數表達式blog
在任何狀況下都是其它JavaScript語句的一部分(好比賦值表達式等號的右側、函數的參數)的函數被稱爲函數表達式。ip
函數表達式最大的問題,在於js會將此代碼拆分爲兩行代碼分別執行。it
例以下代碼:io
console.log(m);//輸出:function m(){} var m=1; function m(){}
實際執行的代碼爲,先將 var m=1 拆分爲 var m; 和 m = 1; 兩行,再將 var m; 和 function m(){} 兩行提高至最上方變成:console
var m; function m(){} console.log(m); m=1;
因此最終函數聲明的m覆蓋了變量聲明的m,輸出結果爲m函數。
m();//m is not defined var m = function(){ console.log('n'); } 這個例子裏雖然變量m聲明提早了,但其後面所接函數表達式仍在原來的位置,因此結果會報錯。
3.比較
//函數聲明 function myFunctionDeclaration(){ function innerFunction() {} } //如下爲函數表達式 var myFunc = function(){}; myFunc(function(){ return function(){}; }); (function namedFunctionExpression () { })(); +function(){}(); -function(){}(); !function(){}(); ~function(){}();
myFunctionDeclaration 是一個包含其它函數聲明(innerFunction)的函數聲明
函數表達式老是其它JavaScript語句的一部分,好比變量聲明等號的右側:
var myFunc = function(){};
或者其餘函數的參數:
myFunc(function() {
return function(){};
});
或者當即執行函數:
(function namedFunctionExpression () { })();
或者被爲運算符修飾:
+function(){}();
函數聲明與函數表達式除了以代碼放的位置不一樣區別,還有一點不一樣,那就是函數聲明必須有函數名,而函數表達式的函數名能夠省略。
函數聲明必須有函數名是由於函數被調用的基本要求,在調用一個函數時咱們必須可以引用它,而惟一的方法就是經過函數名。
函數表達式是其它JavaScript語句的一部分,因此咱們有別的方式引用它們,好比函數被賦值給一個變量,能夠經過變量名來訪問:
var doNothing = function(){}; doNothing();
或者做爲其它函數的參數,能夠經過參數名訪問:
function doSomething(action) { action(); } 關於當即執行函數: 當即執行函數必須用括號包裹,緣由很簡單,JavaScript解析器須要區分函數聲明和函數表達式,若是省略函數外邊的括號,而且直接調用( function(){}(2)此處函數外面沒有括號),JavaScript解析器開始解析,而且結束執行,由於這條語句是以function關鍵字開始,被看成函數聲明,因爲函數聲明必需要有函數名,所以會拋出異常。函數外邊的括號會給JavaScript解析器這是一個函數表達式的信號。爲了達到相同的目的,也能夠這樣寫:(function (a){}(3)),括號的做用和上面相同。位運算符的做用和上面也是相同的。