JS 利用参数个数进行函数重载

分享下《JavaScript忍者秘籍》中的一种函数重载方式

首先说一下函数的length属性:

所有的函数都有一个经常被忽略的属性,但却可以让我们了解函数的声明,那就是length属性。和arguments参数的length属性不同的是,它表示函数声明时所需传入的形参数量。

function makeNinja(name){};
//makeNinja.length === 1;复制代码

对一个函数,在参数方面,我们可以确定两件事情:

  • 通过其length属性,可以知道声明了多少命名参数
  • 通过arguments.length,可以知道在调用时传入了多少参数
重载函数的方法:
/*
* object为要绑定方法的对象
* name为绑定方法所用的属性名称
* fn为要绑定的方法
* */
function addMethod(object, name, fn) {
  //保存原有的函数,因为调用的时候可能不匹配传入的参数个数
  var old = object[name];
  //创建一个新匿名函数作为新方法
  object[name] = function () {
    //如果该匿名函数的形参个数和实参个数匹配,就调用该函数
    if (fn.length === arguments.length) {
      return fn.apply(this, arguments)
    //如果传入的参数不匹配,则调用原有的参数
    } else if (typeof old === 'function') {
      return old.apply(this, arguments);
    }
  }
}复制代码
用法
var ninja = {};
addMethod(ninja, 'whatever', function () {
  /* do something */
});
addMethod(ninja, 'whatever', function (a) {
  /* do something else */
});
addMethod(ninja, 'whatever', function (a, b) {
  /* yet something else */
});复制代码
分析

addMethod()第一次调用将创建一个新匿名函数,传入零个参数进行调用的时候将会调用该fn函数。由于此时ninja是一个新对象,所以这时候不用担心之前创建的方法。

addMethod()第二次调用的时候,首先将之前的同名函数保存到一个变量old中,然后将新创建的匿名函数作为方法。新方法首先检查传入的函数个数是否为一,如果是,就调用刚才传入的fn函数;如果不是,则重新调用存储在old上的函数,重新调用该函数时,将会再次检查参数个数是否为零,继而调用参数个数为零的fn版本的函数。

addMethod()第三次调用的时候,传入了一个接收两个参数的fn函数,然后判断逻辑相同:创建一个匿名函数作为方法,判断是否传入参数的个数为两个,如果是则调用两个参数的fn函数,否则继续判断参数个数是否为一。

这种方法就像剥洋葱一样,每一层都检查参数个数是否匹配,如果不匹配的话,就进入上一层创建的函数。内部函数是通过闭包访问到old和fn的。

这是一个绝佳的技巧,因为这些函数实际上并没有存储于任何典型的数据结构中,而是在闭包里作为引用进行存储。应该注意的是,在使用这个特定的技巧时,需要注意以下两点:

  • 这个重载只适用于不同数量的参数,但并不区分类型、参数名或其他东西。这些才是我们经常想做的事情
  • 这个重载方法会有一些函数调用的开销
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值