在调用函数时,浏览器每次都会传递进两个隐含的参数

  1. 函数上下文对象this
  2. 封装实参对象 arguments

arguments是类数组对象,它可以通过索引来操作数据,也可获取长度,在调用函数时,我们所传递的实参都会在arguments中保存。

既然是对象那其对应也有属性,这里先探讨两个callee,length

length属性

arguments.lenght可以用来获取实参的长度,我们即使不定义形参,也可以通过arguments来使用实参。
arguments[0]表示第一个实参
arguments[1]表示第二个实参
......

//先定义一个函数
function fun(){
console.log(arguments);
console.log(arguments instanceof Array);
console.log(arguments.length);
console.log(arguments[1]);    
console.log(Array.isArray(arguments));
}
fun("hello","thank");

输出结果:
argument.png

callee属性

这个属性对应一个函数对象,就是当前正在指向的函数对象。

function fun(){
 console.log(arguments.callee==fun);
}
fun("hello","thank");//返回true

当然看到这里还是不太清楚这个到底有啥用,这里再介绍几种情景:

  • 可以模拟函数重载

首先我们知道js语法不支持重载,如下:

function fun(a,b){
  return a+b;
}
console.log(fun(1,2));
//再来个同名函数
function fun(a,b,c){
  return a+b+c;
}
console.log(fun(1,2,3));

最后返回值示NaN和6,这就说明后面的函数把前一个同名函数覆盖掉了,从而可以得出js函数不存在重载。
但是使用arguments即可以模拟实现函数的重载,如下:

function fun(){
        //如果用户传入一个参数,求平方
        if(arguments.length==1){
            console.log(arguments[0]*arguments[0]);
        }
        //如果用户传入两个参数,就求和
        if(arguments.length==2){
        //如果用户传入两个参数,就求和
            console.log(arguments[0]+arguments[1]);
        }
    }
    fun(4); //16
    fun(4,5); //9
function add(){
        
       //遍历arguments中每个元素,并累加
        for(var i=0,sum=0;i<arguments.length;i++)
            sum+=arguments[i];
        return sum;//返回和
    }

    console.log(add(1,2,3)); //6
    console.log(add(1,2,3,4,5,6)); //21

这就是JS利用arguments模拟重载的效果。
还有,在js中不需要明确指出参数名,就能访问它们,例如:

function test(){

var s="";     
for(var i=0;i<arguments.length;i++)
    {

   s+=arguments[i]+",";
     }

return s;
}

console.log(test("name","age"));
  • 实现匿名的递归函数

    var sum = function (n) {
          if (1 == n) {
              return 1;
          } else {
              return n + arguments.callee(n - 1); //6 5 4 3 2 1
          }
     }
     alert(sum(6));//21
  • 延伸知识

    var length = 10;
    function fn() {
    console.log(this.length);
    }
    
    var obj = { 
      method: function(fu) {
      fn();
      arguments[0]();
    }
    };
    
    obj.method(fn,1);//输出10,2

    注意函数fn的指向
    第一个值为10,执行的是method里面的第一行"fn()",这里this指向的window。所以输出的值为全局变量的length。
    第二个值为2,虽然arguments[0]()==fun(),但是这里的this指向的是arguments这个对象,所以输出值为arguments的长度。
    另外:arguments对象和Function是分不开的。因为arguments这个对象不能显式创建,arguments对象只有是函数时才可用。

Last modification:April 5, 2020
如果觉得我的文章对你有用,请随意赞赏