JavaScript函数中的arguments对象

原创
2014/12/29 10:20
阅读数 785

        ECMAScript标准中,每个函数都有一个特殊的内置对象arguments。arguments对象是一个类Array对象(object),用以保存函数接收到的实参副本。

一、内置特性

       说它是一个内置对象是因为我们在创建函数时并没有定义这个对象:

var funcTest =function(args){
   console.log(arguments);            
}
funcTest('a');  //{'a'}
console.log(funcTest.arguments);

       直接调用funcTest.arguments输出的结果是null,这一点更可以说明arguments的内置性,当函数开始执行时才能调用到该对象。

二、arguments保存的是函数的实参副本

        在声明一个函数时,函数内部会开辟内存空间用以存储形式参数的变量(指针),这一过程是在定义函数时完成的;而arguments是依据传入的实参而开辟内存空间用以存储实参副本,这一过程是在调用函数时发生的。两者并没有在同一内存空间中存储变量的值。

        1,当实参数量等于形参数量时,两者中的值是同步的:

function funcTest(a,b){
    alert(a);            //1
    alert(arguments[0]); //1
    a='11';
    alert(a);            //11
    alert(arguments[0]); //11
    arguments[0]='22';
    alert(a)             //22
}
funcTest('1','2');

        2,有时它们的值并不同步:

function funcTest(a,b,c){
   alert(arguments[0]);  //1
   alert(c);             //undefined
   c='3';
   alert(arguments[2]);  //undefined
}
funcTest('1','2');

       arguments对象根据传入的实参顺序来与实参的值进行同步,如果该顺序(index)中没有传入实参则不同步。

       3,仅仅是保存实参的副本:

function funcTest(a,b){
   alert(arguments[2])   //undefined
   arguments[2]="1";
   alert(arguments[2]);  //undefined   
}
funcTest('1','2');

       在使用arguments对象时, 在函数内部并不能通过使用arguments[n]的形式来开辟新的内存空间用以保存变量的值,也不能通过该方法增加arguments中的变量数。arguments在函数被调用后即开辟内存空间,该空间数目依据实参数量而来,不可更改。

三、arguments的属性

       1,length属性

       arguments.length返回对象中存储的变量的长度

       2,callee 方法

       arguments.callee返回函数自身的引用

var funcTest=function(){
    alert(funcTest===arguments.callee);   //true
}

      arguments.callee指向函数自身的引用,这在使用匿名函数时会比较有用。

      我们可以利用arguments.callee来创建一个递归函数:

function funcTest(n){
    if(n<=1){
      return 1;
    }else{
      return n*arguments.callee(--n);
    }
}

      也可以用来判断参数数目:

function funcTest(a,b){
    if(arguments.length!=arguments.callee.length){
        alert('传入的参数数目不足!');
    }
}

四、将arguments对象转换成数组(Array)

       开篇语里提到arguments对象是一个类数组对象,是因为它有一些特性和数组很相似,比如有length的属性和类似数组的索引器访问内部变量的特性。但实际上它并不是一个真正的数组。我们可以通过下面的方式将它转换成一个真正的数组:

      var  arr=Array.prototype.slice.call(arguments);

展开阅读全文
加载中
点击加入讨论🔥(5) 发布并加入讨论🔥
5 评论
19 收藏
1
分享
返回顶部
顶部