arguments是指向实参对象的引用。它可以使用方括号语法访问它的每一个元素(即第一个元素是 arguments[0] ,第二个元素是 argumetns[1] ,以此类推),使用 length 属性来确定传递进来多少个参数,但是arguments 对象只是与数组类似,它并不是 Array 的实例。这样说可能好抽象。那么我们来看看简单的例子。
若定义了f函数,它只有一个参数时。而传入两个实参时,就需要用到arguments来获取参数。
function f(x){ alert(x);//输出1 alert(arguments[0]);//输出1 alert(arguments[1]);//输出2 } f(1,2);
当f方法的参数只有一个x时,那么第二个实参就需要通过arguments[1]来获得。同时,arguments包含有一个leng属性。若f方法传入两个参数时,arguments.length的值就是2。
arguments对象最适合的应用场景应该是这样的一类函数,这类函数包含了固定的已经命名的必须参数,以及后面可以传入个数不定的可选的实参。
arguments并不是真正的数组,它是一个实参对象。
function f(x){ alert(x);//输出1 arguments[0]=2; alert(x);//输出2 } f(1);
这个例子可以明显的看出arguments并不是一个普通数组。若是普通数组的话第二个alert就不会输出2。在这个例子里,x和arguments[0]是指代同一个值的,修改其中一个就会影响到另一个。但是在严格的模式下这个arguments是不可以对其进行修改的。
arguments对象的长度是由实参个数而不是形参个数决定的。形参是函数内部重新开辟内存空间存储的变量,但是其与arguments对象内存空间并不重叠。对于arguments和值都存在的情况下,两者值是同步的,但是针对其中一个无值的情况下,对于此无值的情形值不会得以同步。
function f(a, b, c){ alert(arguments.length); // 输出: "2" a = 100; alert(arguments[0]); // 输出: "100" arguments[0] = "qqyumidi"; alert(a); // 输出: "qqyumidi" alert(c); // 输出: "undefined" c = 2012; alert(arguments[2]); // 输出: "undefined" } f(1, 2);
通过length,实现重载。通过判断arguments的length来辨别参数不同的情况。
function doAdd() { if(arguments.length == 1) { alert(arguments[0] + 10); } else if (arguments.length == 2) { alert(arguments[0] + arguments[1]); } }
虽然这个特性算不上完美的重载,但也足够弥补 ECMAScript 的这一缺憾了。
arguments有callee属性(是指针):指向拥有这个arguments对象的函数。
eg:arguments.callee - 获得函数名
可通过这个来实现递归。在使用函数递归调用时推荐使用arguments.callee代替函数名本身。
function count(a){ 2 if(a==1){ 3 return 1; 4 } 5 return a + arguments.callee(--a); 6 } 7 8 var mm = count(10); 9 alert(mm);
通过使用 arguments.callee 代替函数名,可以确保无论怎样调用函数都不会
出问题。因此,在编写递归函数时,使用 arguments.callee 总比使用函数名更保险。
但在严格模式下,不能通过脚本访问 arguments.callee ,访问这个属性会导致错误。不过,可以使用命名函数表达式来达成相同的结果。
var factorial = (function f(num){ return num * f(num-1); });
以上代码创建了一个名为 f() 的命名函数表达式,然后将它赋值给变量 factorial 。即便把函数赋值给了另一个变量,函数的名字 f 仍然有效,所以递归调用照样能正确完成。这种方式在严格模式和 非严格模式下都可以行的通。