讀古今文學網 > 編寫高質量代碼:改善JavaScript程序的188個建議 > 建立58:靈活使用Arguments >

建立58:靈活使用Arguments

JavaScript函數的參數是不固定的,調用函數時傳遞給它的實參也很隨意,為了有效管理參數,JavaScript支持Arguments機制。

Arguments是一個偽數組,可以通過數組下標的形式獲取該集合中傳遞給函數的參數值。例如,在下面這個函數中,沒有指定形參,但在函數體內通過Arguments對象可以獲取傳遞給該函數的每個實參值。


function f{

for(var i=0;i<arguments.length;i++){

alert(arguments[i]);

}

}

f(3,3,6);


Arguments對像僅能夠在函數體內使用,它僅作為函數體的一個私有成員而存在,因此可以通過點號運算符來指定Arguments對像所屬的函數。由於Arguments對像在函數體內是唯一的和可指向的,因此一般會省略前置路徑,直接引用Arguments對象的調用標識符arguments。

通過數組的形式來引用Arguments對像包含的實參值,如arguments[i],其中arguments表示對Arguments對象的實際引用,變量i是Arguments對像集合的下標值,從0開始,直到arguments.length(其中length是Arguments對象的一個屬性,表示Arguments對像包含的實參的個數)。

由於Arguments不是Array的實例,因此不能夠直接調用數組的方法,但通過call或apply方法能夠間接實現調用數組的部分方法。

Arguments對像中的每個元素實際上就是一個變量,這些變量用來存儲調用函數時傳遞的實參值。通過arguments數組和已經命名的形參可以引用這些變量的值。使用Arguments對象可以隨時改變實參的值。例如,在下面這個示例中把循環變量的值傳遞給Arguments對像元素,以實現動態改變實參的值。


function f{

for(var i=0;i<arguments.length;i++){

arguments[i]=i;

alert(arguments[i]);

}

}

f(3,3,6);//提示1、2、3,而不是3、3、6


通過修改Arguments對象的length屬性值,可以達到改變函數實參個數的目的。當length屬性值增大時,增加的實參值為undefined,當length屬性值減小時,則會丟棄arguments數據集合後面對應個數的元素。

Arguments在實際開發中具有重要的價值,使用它可以監測用戶在調用函數時所傳遞的參數是否符合要求,增強函數的容錯能力,同時還可以開發出很多功能強大的函數。

如果要定義的函數參數個數不確定,或者參數個數很多,又不想為每個參數都定義一個變量,此時定義函數可以保留參數列表為空,在函數內部使用Arguments對像來訪問調用函數時傳遞的所有參數。下面這個示例就是利用Arguments對像來計算函數任意多個參數的平均值。


function avg{

var num=0,l=0;

for(var i=0;i<arguments.length;i++){

if(typeof arguments[i]!="number")

continue;

num+=arguments[i];

l++;

}

num/=l;

return num;

}

alert(avg(1,2,3,4));//2.5

alert(avg(1,2,"3",4));//2.3333333333333335


表單驗證是頁面設計中經常要完成的任務,下面的示例驗證所輸入的值是否符合郵箱地址格式。


function isEmail{

if(arguments.length>1)throw new Error("只能夠傳遞一個參數");

var regexp=/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+

((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/;

if(arguments[0].search(regexp)!=-1)

return true;

else

return false;

}

var email="[email protected]";

alert(isEmail(email));//true


Arguments對像包含一個callee屬性,它能夠返回當前Arguments對像所屬的函數引用,這相當於在函數體內調用函數自身。在匿名函數中,callee屬性比較有用,通過它在函數內部引用函數自身。

在下面這個示例中,通過arguments.callee獲取對當前匿名函數的引用,然後通過函數的length屬性確定它的形參個數。最後,通過實參和形參數目的比較來確定傳遞的參數是否合法。


function f(x,y,z){

var a=arguments.length;

var b=arguments.callee.length;

if(a!=b){

throw new Error("傳遞的參數不匹配");

}

else{

return x+y+z;

}

}

alert(f(3,4,5));//值為12


Function對象的length屬性返回的是函數的形參個數,而Arguments對象的length屬性返回的是函數的實參個數。如果函數不是匿名函數,則arguments.callee等價於函數名。