我的编程空间,编程开发者的网络收藏夹
学习永远不晚

详解如何通过JavaScript实现函数重载

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

详解如何通过JavaScript实现函数重载

有的同学在开发中可能遇到过一个困扰,但是很少有人去解决这个问题,我这用一个例子展现出来

const searcher = {};
searcher.findAll = () => {
  console.log("查询所有用户");
};
searcher.findByName = (name) => {
  console.log("按照用户名称查询");
};
searcher.findByFirstNameAndLastName = (firstName, lastName) => {
  console.log("按照姓和名用户查询");
};

可以看到上方的searcher对象有三个方法,但是他的查询逻辑是不一样。 findAll查询所有用户;findByName按照用户名查;findByFirstNameAndLastName是按照姓和名查询用户,结构上没任何问题,那问题在哪?,恶心因为都是在做查询,但又不得不给每一个函数取不同的名字,因为一旦重名就覆盖了,如果说他们能取一样的名字那该有多好

searcher.find = () => {
  console.log("查询所有用户");
};
searcher.find = (name) => {
  console.log("按照用户名称查询");
};
searcher.find = (firstName, lastName) => {
  console.log("按照姓和名用户查询");
};

不传参数就是查所有用户

searcher.find()

给一个参数就是按照用户名来查询

searcher.find("aa")

给两个参数就是按照用户的姓跟名来查询

searcher.find("aa", "bb")

到用得时候也是非常的简单,也符合逻逻辑,这个就叫做函数重载

函数重载:就是给函数取同一样的一个函数名,根据你传递不同的参数数量,分别去调用不同的函数

好处:就在于使用不同的逻辑产生的函数,给他们取一个相同的名字,这样在使用上我只需要记住这个一样的名字就可以了,而不用去记这三个不同的名字,他有效的降低调用函数时产生的心智负担。

但是JS不支持函数重载,所以说如果你写成已上的形式,无论你怎么调用,一定是调用最后一个函数,因为最后一个函数把前面的全部覆盖了
不传参数试一下,你看永远都是走最后一个函数的log

    searcher.find() // 按照姓和名用户查询

那有什么办法呢?在很早的时候jQuery之父John Resig 他就已经提出了一个想法,我们能不能实现一个方法来帮助我们在js中完成函数重载?

于是他想出了一个addMethod方法,就是当我要重载的时,我不直接去定义函数,因为直接定义函数就会出现一个永远只调用最后一个函数的问题,而调用addMethod来定义函数,把对象传进去,把函数的名字传进去,把函数的实现传进去,后面依次同理

addMethod(searcher, 'find', () => {
    console.log('查询所有用户')
})
addMethod(searcher, 'find', (name) => {
    console.log('按照用户名称查询')
})
addMethod(searcher, 'find', (firstName, lastName) => {
    console.log('按照姓和名用户查询')
})

写成这种格式之后,后面调用searcher.find()就能够完成函数重载,问题是这个方法我们得要自己实现,那么如何来实现? 这个方法他接受三个参数,如果你不加处理的话你可能写成下面函数一样,给对象加一个属性,这个属性等于一个函数,调用这个函数实际上就是在运行定义的实现函数fn,把this绑定带过去 然后把传递过来的arguments带过去

function addMethod(object, name, fn) {
  object[name] = function () {
      fn.apply(this, arguments)
  }
}

仅仅这么些还是搞不定,因为每次调用addMethod最后一次调用一定会把object里面同一个属性给覆盖掉,那么如何处理?看下方代码

function addMethod(object, name, fn) {
  const old = object[name];
  object[name] = function () {
    if (arguments.length === fn.length) {
      fn.apply(this, arguments);
    } else if (typeof old === "function") {
      old.apply(this, arguments);
    }
  };
}

首先我不传参数走查询所有用户,传一个参数走按照用户名查询,传两个参数按照姓和名查询

直接看方法体有的同学可能不理解其中的巧妙,我来研究一下这个方法并记录一下执行规则

第一次调用: 通过 old 变量首先保存了之前成员的值,当然这一次保存由于是第一次调用,所以他是一个undefined 然后给object[name]赋值了一个新的函数,这个函数在运行的时候做了一个判断,当你传递的实参数量与你定义函数形参数量一致的时候就执行该函数由此可得:

第二次调用:关键是否则,判断一下old是否是函数,如果是那调用old就会执行上面第一次得出的逻辑,同理可得:

第三次调用:同理可得:

以上是一个注册的顺序,当我们调用时传递0个参数,他会从最后一个开始执行,当形参数量相等就会直接执行当前的方法,如果不相等就会执行old也就是上一个find的逻辑,类似于冒泡执行,等到执行到第一次注册的逻辑判断时形参数量相等了,就直接执行第一次注册的方法,执行打印 "查询所有用户"

searcher.find() // 查询所有用户

总结

其实就是用到了闭包,将闭包形成了闭包链把我们传递的方法依次注册。在调用的时候从最后一个有序的去找,用这种非常巧妙的方式,用极少的代码就实现了一个函数重载的效果,函数重载虽然说你不一定能用到,但是通过去解析这个addMethod,我们可以感受到有这么智慧的实现方案,肯定对你将来实现某一些东西的时候,有所启发。

到此这篇关于详解如何通过JavaScript实现函数重载的文章就介绍到这了,更多相关JavaScript函数重载内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

详解如何通过JavaScript实现函数重载

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

详解如何通过JavaScript实现函数重载

这篇文章主要为大家详细介绍了如何通过JavaScript实现函数重载,文中的示例代码讲解详细,对我们学习JavaScript有一定的帮助,感兴趣的可以了解一下
2023-01-12

C++如何实现函数重载

这篇文章给大家分享的是有关C++如何实现函数重载的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。函数重载函数重载还有一个别名叫函数多态,其实我个人感觉函数多态这个名字更好理解更恰当一些。函数多态是C++在C语言基础
2023-06-25

golang如何实现函数重载?

go 语言不支持传统函数重载,但可以通过以下方法实现类似效果:使用命名函数:为不同参数或返回类型的函数创建唯一名称;使用泛型(go 1.18 及以上):为不同类型参数创建函数的单个版本。Golang 函数重载实现在 Golang 中,并不
golang如何实现函数重载?
2024-04-29

C++中怎么通过C语言实现函数重载

这篇文章给大家介绍C++中怎么通过C语言实现函数重载,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。C++函数重载的相关模拟代码:int (*func)(void); int func1(void) { int
2023-06-17

JavaScript如何实现函数重定义

这篇文章主要介绍JavaScript如何实现函数重定义,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!函数重定义这是一种最基本也是最常用的代码反调试技术了。在JavaScript中,我们可以对用于收集信息的函数进行重定
2023-06-27

VB.NET如何实现过程重载

这篇文章主要介绍了VB.NET如何实现过程重载,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。VB.NET过程重载是指使用相同的名称和不同的参数列表在多个版本中定义某个过程。重
2023-06-17

C++ 函数重载如何实现多态性?

函数重载可用于实现多态性,即通过基类指针调用派生类方法,编译器根据实际参数类型选择重载版本。示例中,animal 类定义虚拟 makesound() 函数,dog 和 cat 类重写该函数,通过 animal* 指针调用 makesound
C++ 函数重载如何实现多态性?
2024-04-13

Java 重载、重写、构造函数的实例详解

Java 重载、重写、构造函数的实例详解方法重写1、重写只能出现在继承关系之中。当一个类继承它的父类方法时,都有机会重写该父类的方法。一个特例是父类的方法被标识为final。重写的主要优点是能够定义某个子类型特有的行为。class Anim
2023-05-31

如何通过IntersectionObserver实现懒加载

这篇文章主要介绍了通过IntersectionObserver实现懒加载,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
2023-05-16

PHP 函数参数类型重载是如何实现的?

php不支持函数重载,但可通过技巧实现类似效果:定义具有相同名称的多个函数,每个函数接受不同类型或数量的参数。在函数调用时,根据参数的类型和数量,使用反射机制确定要调用的函数。该技巧可提高代码可读性、减少错误,但会增加运行时开销。PHP 函
PHP 函数参数类型重载是如何实现的?
2024-04-10

C++ 函数调试详解:如何调试重载函数中的问题?

调试重载函数时,可使用 gdb:设置发生问题的函数断点;附加 gdb 到程序进程;使用 "set print object on" 命令打印变量类型;使用 "step" 和 "print" 命令逐步执行程序,检查变量值。C++ 函数调试详解
C++ 函数调试详解:如何调试重载函数中的问题?
2024-05-03

如何通过vbscript实现文件下载

这篇文章主要介绍了如何通过vbscript实现文件下载,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、VBS下载者:代码如下:Set Post = CreateObject
2023-06-08

编程热搜

目录