arguments对象
arguments对象是一个特殊的类数组对象(不是数组),它代表传给一个函数的参数列表。arguments对象是函数内部的本地变量,并非函数的属性。
我们可以通过数组下标的形式来访问具体的参数。
arguments[0];
arguments[1];
arguments[2];
参数也可以被重新赋值:(但是我们不推荐这种做法)
arguments[1]="value";
因为arguments对象并不是一个真正的数组,所以它不能使用数组所特有的属性和方法,但它拥有length属性。但是我们可以将其转换为数组:
var args=Array.prototype.slice.call(arguments);
//另外一种写法
var args=[].slice.call(arguments);
arguments.callee
callee是arguments对象的属性。在函数体内,它指向当前正在执行的函数。
ECMAScript 5 禁止在严格模式中使用 arguments.callee()。当一个函数必须调用自身的时候,假如它是函数表达式则给它命名,或者使用函数声明,避免使用 arguments.callee()
使用arguments.callee最常见的情景是当我们要创造一个递归函数的时候:
(function(n){
return !(n>1)?1:arguments.callee(n-1)*n;
}).call(this,5);
//120
但是如果我们写成:
(function(n){
return !(n>1)?1:(n-1)*n;
}).call(this,5);
//20
为了解决这个问题,我们才使用了arguments.callee
实际上这是一个糟糕的解决方案,因为递归调用会获取到不同的this值:
var global=this;
var badRecursive=function(r){
if(!r){return arguments.callee(true);}
if(this!==global){
alert("This is:"+this);
}else{
alert("This is global");
}
}
badRecursive(true);//"This is global"
badRecursive(false);//"This is[object Arguments]"
因此用命名函数表达式可以解决这些问题,例如:
[1,2,3].map(function recursive(n){
return !(n>1)?1:recursive(n-1)*n;
});