arguments

2019-07-24  本文已影响0人  haha2333

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

上一篇下一篇

猜你喜欢

热点阅读