Javascript支持Arguments机制.Arguments是一个为数组,可以通过数组下标形式获取该集合中传递给函数的参数值.例如:下面函数中,没有指定形参,但在函数体内通过Arguments对象可以获取传递给该函数的每个参数值.
function f(){ for(var i = 0;i<arguments.length;i++){ console.log(arguments[i]); } } f(1,3,6) //1 3 6
Arguments对象仅能够在函数体内使用,它仅作为函数体的一个私有成员而存在,因此可以通过点号运算符来指定Arguments对象所属的函数.由于Arguments对象在函数体内是唯一和可指向的,因此一般会省略前置路径,直接引用对象的调用标识符arguments.
通过数组的形式来引用Arguments对象包含的实参值,如arguments[i],其中arguments表示对Arguments对象的实际引用,变量i是 Arguments对象集合的下标值,从0开始,知道arguments,length(其中length是Arguments对象的一个属性,表示Arguments对象包含的实参的个数).
由于Arguments不是Array的实例,因此不饿能够直接调用数组的方法,但是能够通过call或apply方法间接实现.
下面把循环变量的值传给Arguments对象元素,以实现动态改变实参的值
function f(){ for(var i = 0;i<arguments.length;i++){ arguments[i] = i console.log(arguments[i]); } } f(2,3,6) // 0 1 2 而不是 2 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++ } console.log(l); num /= l return num } console.log(avg(1,2,3,4)); //2.5 console.log(avg(1,2,3,"4")); //2
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; } } console.log(f(3,4,5)); //12 console.log(f(2,3)); //Uncaught Error: 传递的参数不匹配
Function对象的length属性返回的是函数的形参个数,而Arguments对象的length属性返回的是函数的实参个数.如果函数不是匿名函数,则arguments.callee等价于函数名.