×

JavaScript深入理解函数 - 函数的内部属性

作者:Terry2016.09.27来源:Web前端之家浏览:12635评论:0

600.png

在JavaScript函数的内部有2个特殊的对象:argumentsthis

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和一个显示颜色的方法showColorshowColor方法引用的是外部的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对象就是这个调用方法的对象。

返回javascript教程主目录>>

您的支持是我们创作的动力!
温馨提示:本文作者系Terry ,经Web前端之家编辑修改或补充,转载请注明出处和本文链接:
https://jiangweishan.com/article/js1474905600995.html

网友评论文明上网理性发言 已有0人参与

发表评论: