Javascript中的arguments对象
实参和形参的同步性
实参是存储在arguments对象中,arguments是一个类数组,arguments对象的长度是由实参个数而不是形参个数决定的。形参是函数内部重新开辟内存空间存储的变量,但是其与arguments对象内存空间并不重叠。对于arguments和值都存在的情况下,两者值是同步的,但是针对其中一个无值的情况下,对于此无值的情形值不会得以同步。下面的截图可以验证
形参a与实参arguments[0]是对应关系,改动其中一个,另外一个也会跟着改变。但是对于形参c和实参arguments[2]而言,因为实参有“1”、“2”,arguments[2]并没有赋值,所以arguments[2]为undefined,在函数中将arguments[2]对应的形参c赋值为2012后,arguments[2]仍为undefined。
arguments的callee属性
callee属性在函数的递归当中较常出现,下面对比一下递归中使用callee和不使用callee的区别
不使用callee的递归写法:
以下代码可导致出错:
var tempCount = count;
count = null;
alert(tempCount(3)); //出错
由于tempCount和count本质只是指向函数的指针,在执行tempCount(3)时,函数体内会调用count指向的函数,而count已经被置为null,count不指向函数了,所以出错。
用arguments.callee可解决问题,这是一个指向正在执行的函数的指针。
使用callee的递归写法:
var tempCount = count;
count = null;
alert(tempCount(4)); //结果为24.
补充:1.函数没有重载,只有覆盖,2.事件函数,有默认参数event
在js中有两个原因导致没有函数重载,一:函数没有返回值类型这一说法,二:形参只是用来在函数中方便调用的,编译并不检查传参,实参是存储在arguments对象中。对此举个例:
由此可以看出,调用的始终是后面的申明的函数。
对于事件函数的默认参数event问题,贴一段代码:
对应的打印:
其实有些人对上面的函数开始会有这样的第一反应:arguments.length = 2, arguments里面是foo和1000,但是,仔细观察一下,发现arguments是返回的匿名函数的arguments,而不是debounce的arguments。匿名函数并没有任何形参也没有明显传递实参,但是打印出的arguments.length = 1,并且打印出的这个实参是event。这是因为debounce函数执行后,返回的匿名函数作为window的mousemove函数,事件函数里面会有一个默认的参数event,这是事件函数特有的情况,但是如果是一个普通的匿名函数,就不会有默认的event参数。