arguments

作者: haha2333 | 来源:发表于2019-07-24 16:35 被阅读0次

    js函数不能像传统意义上那样实现函数重载。所谓的函数重载就是:为一个函数编写两个定义,只要这两个定义的签名(接受的参数的类型和数量)不同即可。执行时判断参数个数,哪个函数参数个数吻合,则调用哪个

    function aa(){
      console.log("a")
    }
    function aa(b){
      console.log("b")
    }
    aa()  //b
    

    但是在js中后面声明的函数定义会覆盖前面的,所以不存在函数重载。
    那么js进行函数重载是依靠什么的呢?

    arguments

    它是JS的一个内置对象,每一个函数都有一个arguments对象,它包括了函数实际被传入的参数,用法与数组一样,但它却不是数组。使用instanceof会报错
    比如访问传入函数的第一个参数:arguments[0]
    传入参数的个数:arguments.length
    这样不需要指出参数名,也可以访问他们

    function test() {
            var s = "";
            for (var i = 0; i < arguments.length; i++) {
                alert(arguments[i]);
                s += arguments[i] + ",";
            }
            return s;
    }
    test("name", "age");
    
    输出结果:
    name,age
    

    具体实现函数重载

    函数的 length 属性,返回的是函数定义时形参的个数
    object:要绑定方法的对象,
    name:绑定的方法名称,
    fn:需要绑定的方法
    每调用一次 addMethod 函数,就会产生一个 old,形成一个闭包。

    function addMethod (object, name, fn) {
      // 先把原来的object[name] 方法,保存在old中
      var old = object[name];
    
      // 重新定义 object[name] 方法
      object[name] = function () {
        // 如果函数需要的参数 和 实际传入的参数 的个数相同,就直接调用fn
        if (fn.length === arguments.length) {
          return fn.apply(this, arguments);
    
          // 如果不相同,判断old 是不是函数,
          // 如果是就调用old,也就是刚才保存的 object[name] 方法
        } else if (typeof old === "function") {
          return old.apply(this, arguments);
        }
      }
    }
    

    使用:
    find0、find1、find2方法自己定义

    // 给 users 对象添加处理 没有参数 的方法
    addMethod(users, "find", find0);
    
    // 给 users 对象添加处理 一个参数 的方法
    addMethod(users, "find", find1);
    
    // 给 users 对象添加处理 两个参数 的方法
    addMethod(users, "find", find2);
    
    // 测试:
    console.log(users.find()); //["Dean Edwards", "Alex Russell", "Dean Tom"]
    console.log(users.find("Dean")); //["Dean Edwards", "Dean Tom"]
    console.log(users.find("Dean","Edwards")); //["Dean Edwards"]
    

    把arguments转换成一个真正的数组

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

    创建引用自身的函数

    callee属性是 arguments 对象的一个成员,callee 属性的初始值就是正被执行的 Function 对象。实现匿名的递归函数。

    var sum = function (n) {
            if (1 == n) {
                return 1;
            } else {
                return n + arguments.callee(n - 1);
            }
       }
       alert(sum(6));  //21
    

    注意点:

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

    第一个fn()自执行,没有上下文调用,所以this指向window,第二个arguments[0]()即是arguments[0] () => fn() ,这里this执行的是arguments这个对象,所以输出值为arguments的长度2

    相关文章

      网友评论

          本文标题:arguments

          本文链接:https://www.haomeiwen.com/subject/nfwglctx.html