function f(){
alert(f.arguments==arguments); //true
};
alert("arguments" in f); //true
alert(f.arguments); //null
f();
arguments这个对象的作用是保存函数在运行期间的一些参数。当我们调用函数时,传入的参数会在arguments中以拟数组方式储存。它和数组一样提供了length属性,但却没有数组的方法。因此它只是一个拟数组而不是真正的数组。不过虽然不是真正的数组,我们也依然可以让数组的方法去主动调用它,比如这样调用function join(){
return Array.prototype.join.call(arguments);
};
alert(join("a","b","c"));
也可以把它当成数组,作为apply的参数来使用,比如一个获取最大值的函数function max(){
return Math.max.apply(null,arguments);
};
alert(max(5,2,7));
这是它作为拟数组的性质,而这个arguments本身也有自己的性质。它的参数列表和对应的形参使用的是相同的数据地址,或者说形参就是某个arguuments参数列表项的别名。看下面代码就会明白(function(a){
a="我主页";
alert(arguments[0]); //我主页
})("测试");
这个例子中a和arguments[0]是共用的数据地址,所以给a赋值后arguments[0]的值也会改变。接着是arguments中一个关键的属性callee。这个callee指的就是函数自身,可以用一段代码来验证。function f(){
alert(arguments.callee===f); //true
};
f();
我们经常会在匿名函数的递归中使用callee。由于匿名函数没有变量来保存它的句柄,所以只能在运行时候通过callee来获取,以实现递归。(function(){
console.log("我主页");
setTimeout(arguments.callee,1000);
})();
像上面这样每秒一次的慢递归,这种方法可以节省一个变量名,非常推荐使用。但是对于需要效率的递归就不建议这样使用,因为在某些引擎中对arguments处理是非常复杂的,这就会影响效率。这个问题在之前的文章“JavaScript调用堆栈对变量访问效率有影响!?”中有提到过。即使arguments什么都没做,只是被一个分号结束也是非常影响效率的,所以在需要高效的代码中尽量避免引入arguments。
转载请注明:前端录»JavaScript的arguments及其子对象