javascript 函數詳解2 -- arguments
今天我們接著上篇文章來繼續javascript函數這個主題。今天要講的是函數對像中一個很重要的屬性--arguments。
相關閱讀:
arguments對象參數數組引用
arguments是函數對象內部一個比較特殊的類數組對象,這個對象中包含了所屬函數的參數列表,同時還包含一個指向函數原型對象的指針.
我 們先來討論下arguments中的參數數組,我們可以直接使用[index]的類似訪問數組的方式來訪問參數。要真正理解這特性,我們先要知道 javascript的函數不關心你傳遞的參數,因為在調用函數的時候,在函數內部他接收的是一個參數數組,也就是說,理論上,我們可以在聲明函數的時候 可以不聲明任何參數,但是在調用的時候卻可以傳遞任意多的參數。
如下代碼示例:
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對象與參數列表的引用關系。
function dosum(op1,op2){ arguments[1] = 20; console.log(arguments[0]+op2); } dosum(1,1);
我們先預測下執行結果,2還是21?
真正的執行結果如下:
針對上面的執行結果我們可以抽象下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,這時我們就可以在其他地方繼續調用這個函數。
這樣的用法是我在項目中遇到的,頁面初始化時要做一些操作,也就是頁面加載完成后立即執行該函數,但是這個函數并不是一次性的,我們還需要在該頁面的其他時候來調用這個函數,上面的代碼,個人會比先聲明一個函數,然后在頁面加載完成后調用要優雅一些,見仁見智罷了。
原文來自:javascript 函數詳解2 -- arguments