今天咱們接着上篇文章來繼續javascript函數這個主題。今天要講的是函數對像中一個很重要的屬性--arguments。javascript
相關閱讀:java
arguments對象參數數組引用數組
arguments是函數對象內部一個比較特殊的類數組對象,這個對象中包含了所屬函數的參數列表,同時還包含一個指向函數原型對象的指針.函數
咱們先來討論下arguments中的參數數組,咱們能夠直接使用[index]的相似訪問數組的方式來訪問參數。要真正理解這特性,咱們先要知道javascript的函數不關心你傳遞的參數,由於在調用函數的時候,在函數內部他接收的是一個參數數組,也就是說,理論上,咱們能夠在聲明函數的時候能夠不聲明任何參數,可是在調用的時候卻能夠傳遞任意多的參數。this
以下代碼示例:spa
function sayHi(){ var name = arguments[0]||"default name", greeting = arguments[1]||" how are you"; console.log("Hello "+name+","+ greeting); } //不傳參數調用 sayHi(); //傳一個參數調用 sayHi("John"); //傳兩個參數調用 sayHi("John","你好!");
執行結果:指針
接下來咱們在看另一段代碼,來探索arguments對象與參數列表的引用關係。code
function dosum(op1,op2){ arguments[1] = 20; console.log(arguments[0]+op2); } dosum(1,1);
咱們先預測下執行結果,2仍是21?htm
真正的執行結果以下:對象
針對上面的執行結果咱們能夠抽象下argument與參數數組間的引用管理模型。
arguments callee屬性
arguments callee屬性是一個指向函數對象的指針,靈活使用該屬性能夠大大下降代碼與函數名的耦合度,同時能夠使代碼更加靈活。
下降耦合度通常在遞歸運算中體現比較明顯。
以下代碼:
function factorial(num){ if(num<=1){ return 1; } else{ return num*factorial(num-1); } }
上面這段代碼最大的缺點就是與函數名factorial的耦合,正如咱們一開始講的,函數名是一個指針,也就是一個變量,若是咱們能保證該變量一直引用該函數對象,那麼這段代碼就一直能返回咱們所指望的結果。一旦該變量指向了其餘對象,上面的代碼就會出錯,這時候 arguments.callee就可以發揮做用了。修改以下:
function factorial(num){ if(num <= 1){ return 1; }else{ return num * arguments.callee(num -1 ); } }
這樣,這個函數對象的計算結果就與函數名factorial沒有關係了,就算以後作以下操做,咱們依舊能夠獲得正確的結果。
var afunc = factorial;
factorial = null;
afunc(3); // 一樣能夠正確返回6
經過arguments.callee的另一個比較靈活的應用以下:
var otherfunc = (function(){ console.log("do something cool"); return arguments.callee; })();
上面代碼所作的操做時當即執行了一個函數,並返回該匿名函數的引用,賦值給otherfunc,這時咱們就能夠在其餘地方繼續調用這個函數。
這樣的用法是我在項目中遇到的,頁面初始化時要作一些操做,也就是頁面加載完成後當即執行該函數,可是這個函數並非一次性的,咱們還須要在該頁面的其餘時候來調用這個函數,上面的代碼,我的會比先聲明一個函數,而後在頁面加載完成後調用要優雅一些,見仁見智罷了。