argunments对象

 MDN解释:arguments 是一个对应于传递给函数的参数的类数组对象。

 arguments的使用  

  当我们不确定有多少个参数传递的时候,可以用arguments来获取。在js中,arguments实际上是当前函数的一个内置对象。所有的函数都内置了一个arguments对象,arguments对象中存储了传递的所有实参。具体使用格式如下

function func1(a, b, c) {
  console.log(arguments[0]);
  //  1

  console.log(arguments[1]);
  //  2

  console.log(arguments[2]);
  //  3
}

func1(1, 2, 3);

  实际上,arguments对象是所有(非箭头)函数中都可用的局部变量。你可以使用arguments对象在函数中引用函数的参数。此对象包含传递给函数的每个参数,第一个参数在索引0处

  此外,arguments展示的形式是一个伪数组(类数组对象),因此可以进行遍历。伪数组具有一下特点:

  • 具有length属性
  • 按索引方式存储数据
  • 不具有数组的push、pop等方法

 但是它可以被转换为一个真正的Array

var args = Array.prototype.slice.call(arguments);
var args = [].slice.call(arguments);

  最后,arguments对象其实还有一个callee属性,是一个指向arguments对象所在函数的指针

    function foo() {
        console.log(arguments.callee === foo);//true
    }
    foo(5);

 

 例子  

1、遍历参数求和

function add() {
    var sum =0,
        len = arguments.length;
    for(var i=0; i<len; i++){
        sum += arguments[i];
    }
    return sum;
}
add()                           // 0
add(1)                          // 1
add(1,2,3,4);                   // 10

 

2、callee属性阶乘函数的例子

 首先我们来看看下面的阶乘函数

  function foo(num) {
        if(num <= 1){
            return 1;
        }else{
            return num * foo(num - 1);
        }
    }

 阶乘函数一般定义成递归调用的,就像上面的这个例子一样。只要给函数一个名称,而且这个名称不会变,这样定义就没有问题。但是这个函数正确执行就必须保证函数名是foo,从而导致了紧密耦合,使用arguments.callee就可以让函数逻辑与函数名解耦:

     function foo(num) {
        if(num <= 1){
            return 1;
        }else{
            return num * arguments.callee(num - 1);
        }
    }

 这个重写后的foo()函数已经用arguments.callee代替之前硬编码的foo。这意味着无论函数叫什么名称,都可以引用正确的函数。如下:

    function foo(num) {
        if(num <= 1){
            return 1;
        }else{
            return num * arguments.callee(num - 1);
        }
    }
    let trueFoo = foo;
    foo = function () {
        return 0;
    }

    console.log(trueFoo(5));//120
    console.log(foo(5));//0

 trueFoo变量被赋值为foo,实际上把同一个函数的指针又保存到另一个位置。然后foo函数又被重写为一个返回0的函数。如果像之前的版本不使用callee,那么象上面那样调用trueFoo就会返回0。

 

posted @ 2021-10-16 15:51  打遍天下吴敌手  阅读(103)  评论(0编辑  收藏  举报