函數的實參和形參個數能夠不等,之因此會這樣,緣由是 ECMAScript 中的參數在內部是用一個數組來表示的。函數接收到的始終都是這個數組,而不關心數組中包含哪些參數(若是有參數的話)。若是實參個數大於形參個數,多餘的實參不傳遞值,可是在arguments中能夠訪問;若是形參個數大於實參,沒有傳遞值的實參將自動被賦予 undefined 值。編程
全部的函數調用都會傳遞兩個隱式參數:arguments和this。
實際上,在函數體內能夠經過 arguments對象來訪問這個參數數組,從而獲取傳遞給函數的每個參數。arguments 對象只是與數組相似(它並非 Array 的實例),由於可使用方括號語法訪問它的每個元素(arguments[0]、argumetns[1]…),也使用 length 屬性來肯定傳遞進來多少個參數。數組
arguments對象的值永遠與對應命名參數的值保持同步:app
function doAdd(num1, num2) { arguments[1] = 10; alert(arguments[0] + num2); }
由於 arguments對象中的值會自動反映到對應的命名參數,因此修改 arguments[1],也就修改了 num2,結果它們的值都會變成 10。不過,這並非說讀取這兩個值會訪問相同的內存空間;它們的內存空間是獨立的,但它們的值會同步。另外還要記住,若是隻傳入了一個參數,那麼爲 arguments[1]設置的值不會反應到命名參數中(num2保持undefined)。這是由於 arguments 對象的長度是由傳入的參數個數決定的,不是由定義函數時的命名參數的個數決定的。函數式編程
this參數引用函數的上下文,函數上下文來自於Java等面嚮對象語言,Java中的this依賴於函數聲明。可是和Java不一樣,JavaScript中的this依賴於函數的調用方式,所以把this稱爲調用上下文很合適。通常函數有四種調用方式:簡單函數調用;對象方法調用;做爲構造函數調用;經過apply()和call()調用。這四種方式的主要區別就在於調用上下文不一樣:簡單函數調用的上下文是window對象,方法調用的上下文是對象,構造函數的上下文是是新建立的對象實例。這些調用中函數的this指向都是固定的,可是隻有apply()和call()調用能夠自主定義上下文。函數
區別在於接收參數的方式不一樣:apply(argu1,argu2),argu1是函數運行的做用域(this),argu2是參數數組,能夠傳入arguments 對象或者參數數組;call(argu1,argu2), argu1是this,argu2是逐個列出的函數參數。
若是你打算直接傳入 arguments 對象,或者包含函數中先接收到的也是一個數組,那麼使用 apply()確定更方便;不然,選擇 call()可能更合適。(在不給函數傳遞參數的狀況下,使用哪一個方法都無所謂。)
傳遞參數並不是 apply()和 call()真正的用武之地;它們真正強大的地方是可以擴充函數賴以運行的做用域。使用 call()(或 apply())來擴充做用域的最大好處,就是對象不須要與方法有任何耦合關係。this
當須要爲函數指定上下文時,就有必要使用apply()和 call()了,一個具體的例子就是回調函數。假如對數組中的每一個元素進行一次操做,命令式編程方式通常使用for循環遍歷數組元素,可是函數式編程是編寫一個函數,而後對每一個數組元素運行該函數,區別在於函數式編程更有利於代碼複用。對每一個數組元素運行該函數有兩種思路,一種是把數組元素做爲參數傳入,一種是把數組參數做爲函數運行的上下文,這時就能夠用到apply()和 call()。spa
function forEach(list, callback){ for(var n=0; n<list.length; n++){ callback.call(list[n], n); } } var colors = ["blue", "red","green"]; var res = []; forEach(colors, function(index){ res[index] = (this == colors[index]); return res;//true,true,true }); alert(res);
使用callback回調函數的call方法,將當前數組元素做爲第一個參數傳入,將當前數組索引做爲第二個參數傳入,這使得當前元素變爲函數上下文,索引值做爲callback()的參數。在callback()內部驗證當前元素是不是上下文。code
ECMAScirpt函數沒有簽名,由於其參數是由包含零或多個值的數組來表示的。而沒有函數簽名,真正的重載是不可能作到的。若是在 ECMAScript 中定義了兩個名字相同的函數,則該名字只屬於後定義的函數。
函數重載定義:重載函數是函數的一種特殊狀況,爲方便使用,C++容許在同一範圍中聲明幾個功能相似的同名函數,可是這些同名函數的形式參數(指參數的個數、類型或者順序)必須不一樣,也就是說用同一個運算符完成不一樣的運算功能。這就是重載函數。重載函數經常使用來實現功能相似而所處理的數據類型不一樣的問題。對象