在JavaScript函数的内部有2个特殊的对象:arguments
和this
。
arguments对象
arguments
是一个类数组对象,通过该对象可以获取相应的参数值。例如下面的代码:
function fn1(arg){
return arg * 10;
}
fn1(1,2,3);
//打印函数fn1的参数
for(var i = 0; i < arguments.length; i++){
console.info(arguments[i]);
}
虽然函数fn1()
在调用的时候只会匹配第一个参数,但是所有的参数都保存在arguments
对象中。通过上面的方法就可以查看传入函数的所有参数。
在arguments
对象中有一个callee()
方法。通过该方法可以反向调用函数。最经典的例子是求阶乘的例子,代码如下:
//求阶乘函数
function factorial(num){
if(num <= 1){
return 1
}else{
return num * factorial(num - 1);
}
}
由于在JavaScript中函数名称是可以改变的,上面求阶乘的方法中递归调用的函数名和原有的函数名耦合在一起了,如果将来这个函数名称被更改了,递归调用就会失败。例如:
var cf = factorial;
console.info(cf(5)); //此时不会报错,输出120
//如果我们将factorial函数置空,就会出现问题
factorial = null;
console.info(cf(5)); //此时会报错:"Uncaught TypeError: factorial is not a function"
由于cf
函数中依然使用factorial
这个函数名来调用,但是factorial
已经指向了null,所以会报错。解决这个问题的方法就是使用arguments.callee
方法来调用。
//使用arguments.callee来完成递归调用
function factorial(num){
if(num <= 1){
return 1
}else{
return num * arguments.callee(num - 1);
}
}
在JavaScript中,通常都是使用arguments.callee
方法来完成递归调用的。
this对象
通过前面的学习我们知道,在我们需要创建一个类的时候,设置类的属性和方法需要通过this关键字来引用。但是特别要注意:this关键字在调用时会根据不同的调用对象而变得不同。来看下面的例子:
var color = "red";
//定义一个函数
function showColor(){
console.info(this.color);
}
//创建了一个类
function Circle(color){
this.color = color;
this.showColor = showColor;
}
var c = new Circle("yellow");
在上面的代码中,首先创建了一个showColor()
函数,这个函数会在控制台打印一个颜色信息。接着创建了一个Circle
类型,它有一个属性color
和一个显示颜色的方法showColor
,showColor
方法引用的是外部的showColor
函数。下面我们来看看使用不同的上下文对象来调用showColor
方法的结果。
c.showColor(); //showColor()方法的调用者是对象c,所以this == c
在上面这个方法调用中,使用的是对象c来调用showColor
方法,此时的this
对象就是c,所以控制台中打印的颜色应该是"yellow"。
showColor(); //此时调用showColor()方法的对象是window,所以this == window
如果直接调用showColor()
方法,那么该方法的调用者是window
对象,showColor
中的this
就是window
,所以控制台中打印出来的颜色是"red"。
判断this
对象的关键是看谁调用了方法,是谁调用的方法,this
对象就是这个调用方法的对象。