函数学习之参数(arguments对象)

 函数声明语句:function f(x){},其中x就是参数。javascript

参数分为两种:java

  • 形参(parameter):函数定义时圆括号里的数据。
  • 实参(arguments);函数调用时,传给函数做为参数的数据。

EMCAScript规定在调用函数时,可传入任意数量,任意类型的参数,能够不跟函数定义时传入的形参数量相对应。为何会这样呢?数组

缘由就是,EMACAScript中的参数在内部是用一个数组来表示的,函数接收的始终是这个数组,而不关心包含哪些参数。并且,在函数体内也能够经过arguments这个对象来访问这个参数数组,从而获取传递给函数的每个参数。(arguments就是一个对象--函数的一个内部对象,和this同样。)所以arguments看起来就像一个类数组了。能够用arguments[n]来访问各个位置的元素了.函数

 

要了解arguments对象,就须要先函数的内部属性。this

函数内部,有两个特殊对象:arguments 和 this。spa

arguments是一个类数组对象,包含着传入函数中的全部参数。该对象有一个属性callee,该属性是一个指针,指向拥有这个arguments对象的函数。经典例子是阶乘函数:指针

 1 function factorial(num){
 2     if(num <= 1){
 3         return 1;
 4     }else{
 5         return num * factorial(num-1);
 6     }
 7 }
 8 
 9 //修改一下,消除函数的执行与函数名紧密的耦合在一块儿,
10 function factorial(num){
11     if(num <= 1){
12         return 1;
13     }else {
14         return num * arguments.callee(num-1);
15     }
16 }
17 
18 //修改后函数名factorial就没出如今函数体内部,所以,不管引用函数时使用什么名字,都能保证正常完成递归。
19 //例如
20 var trueFactorial = factorial;
21 factorial = function(){
22     return 0;
23 };
24 alert(trueFactorial(5));  //120
25 alert(factorial(5));   //0
26 //在上面的例子里,变量trueFactorial 得到了factorial的值,实际上就是在另外一个位置上保存了一个指向函数的指针,就是让另外一个变量也能够应用该函数,正如在函数定义时说的,函数名是一个指向函数的指针,函数体自己存在那里,经过函数名能够访问罢了,两者相互独立,又存在某种联系。 27 //而后将一个返回0的新函数赋给变量factorial。若是在函数体内有变量名factorial,如第一个例子,则trueFactorial()就会返回0.但改为arguments.callee后就可以让trueFactorial正常计算。

与callee属性对应的就是caller属性,arguments对象也拥有caller属性,即:arguments.caller。但在严格模式下访问它会报错,而在非严格模式下这个属性始终是undefined。该属性主要就是为了分清arguments.caller和函数的caller属性。函数的caller属性指向调用该函数的外部函数。code

arguments.callee.caller 和函数的caller属性等效。对象

function outer(){
    inner();
}
function inner(){
    alert(inner.caller);  //等价于alert(arguments.callee.caller);
}
outer();   //返回outer函数的代码

 

arguments还有一个length属性,返回传入参数的个数。和Array.length相似。blog

 

前面说的在函数内部能够经过arguments对象访问传入的参数。那也能够和命名参数一块儿在函数内部使用:

function doAdd(num1,num2){
    if(arguments.length == 1){
        alert(num1 + 10);
    }else if(arguments.length == 2){
        alert(arguemnts[0] + num2);
    }
}

还有一点。arguments的值永远与对应的命名参数保持同步:

function doAdd(num1,num2){
    arguments[1] = 10;
    alert(arguments[0] + num2);
}

  什么意思呢?就是每次执行这个函数时,里面的arguments[1]都会被设成10,对应的num2也会跟着变着10。

最后一点:没有传递值的命名参数将自动被赋予undefined,就像变量没有初始化同样。

关于函数定义时的参数,其实就像在函数内部定义的变量同样,只不过不用在显性的使用var来进行定义。

相关文章
相关标签/搜索