在js中,我们实现重载常用的方式有:

1、根据传入参数的类型执行不同的操作。

2、利用参数中特殊的参数值进行不同的操作。

3、根据参数的个数进行重载。

这里对第三种重载方式的实现进行说明。

实现第三种方法,最简单的就是使用switch case进行参数个数的判断,然后执行相应的操作,但这样的判断方法导致代码不是很整洁,逼格也不算是太高。

如:

function fn() {
switch (arguments.length) {
case 0:
//执行语句块
break;
case 1:
//执行语句块
break;
case 2:
//执行语句块
break;
default:
break;
}
}

下面介绍一种方法,先不考虑是否适用,但可以通过了解这种重载方式,让我们学到一些JS中的技巧和对闭包的一些理解。毕竟多了解些不算件坏事。

先上代码:

var arr = {
value: ["a", "b", "c"]
};
bindMethod(arr, "find", function () {
console.log(0)
});
bindMethod(arr, "find", function (a) {
console.log(1)
});
bindMethod(arr, "find", function (a, b) {
console.log(2)
});
function bindMethod(obj, name, fn) {
var old = obj[name]; //每个方法中都会存在一个各自的old对象,产生了闭包
obj[name] = function () {
if (fn.length == arguments.length) { //这里的fn.length是方法定义参数的个数,和arguments.length传入的个数是两回事
return fn.apply(this, arguments); //返回传入在匿名函数,执行
}
else {
return old.apply(this, arguments); //返回数组的方法,再次向上进行查找
}
}
}
arr.find(); //
arr.find(1); //
arr.find(1, 2); //
arr.find(1, 2, 3); //Uncaught TypeError: Cannot read property 'apply' of undefined /**
第一次进行绑定时,先赋值old,因为attr.find并没有被创建,所以old=undefined。然后为arr对象find属性创建一个匿名方法,这个匿名方法fn.length=0。
第二次进行绑定时,将old对象指向第一次创建的匿名方法,然后会将arr对象find属性指向到当前创建的匿名方法,因为old指向上个方法的引用,这就会造成上个方法不会被释放。
第三次也是一样的步骤,保证第二次绑定的方法不会被释放。
重载方法的执行,像一个链条一样,先从最后绑定的方法内部开始寻找 方法定义的参数个数和传入的个数是否匹配,如果匹配则返回当前的传入的匿名函数,否则继续向上查找,直到找到为止。
如果最后没有找到结果,当前程序会报错,因为第一次绑定方法时,old对象是一个undefined
**/

绑定阶段

先将arr绑定三个方法,每个方法都有一个old的对象,存放之前保存的方法,以此类推,(当前的方法中,old对象都会指向上一次绑定方法,但是注意,在第一次绑定的方法中,old对象是undefind),这样就可以形成一个链条。也就是说内存中分别有三个attr.find的内存空间,都指向各自创建bindMethod内的匿名方法。

调用阶段
当传入0个参数,进行调用时,会先调用最后一个绑定的方法。然后进行判断,如果传入参数为2个,则返回匿名方法,否则
调用old指向的上个方法。再次进入,再次进行判断,直到找到符合参数个数的方法,返回它的匿名函数。

在这里对于attr对象的绑定,其实是进行了三次绑定覆盖的操作,依次进行对attr.find进行赋值,最后只保留最后一次的赋值对象。

这也是为什么在进行调用时,是从最后一次绑定的方法中开始执行的原因。对于attr.find方法被覆盖,但却没有被自动释放的原因是因为新方法的old

始终指向被覆盖的方法,所以这里产生了闭包。

JS实现重载的更多相关文章

  1. JS函数重载解决方案

    JS的函数定义可以指定形式参数名称,多多少少我们会以为js至少可以支持参数个数不同的方法重载,然而遗憾的是这仅仅是一个假象,js所有的参数都是以arguments传递过去的,这个参数类似于数组,在函数 ...

  2. js没有重载

    javascript与其他语言(如java)不同,它没有传统意义上的重载(即为函数编写两个定义,只要这两个函数的参数类型或数量不同即可),在js中,后定义的函数会覆盖先前的函数.js中的参数在内部是用 ...

  3. js中重载问题

    在js中是没有重载的  但是  Arguments对象(可以实现模拟重载的效果) 利用arguments对象的length属性,可以获取函数接收的参数的个数 例如: function add(){ i ...

  4. js方法重载

    test(5); test(5,5); function test(a){ alert(a); } function test(a,b){ alert(a+b); } NaN和10,说明第二个覆盖了第 ...

  5. JS 模拟 重载

    重载:方法,根据传入的参数列表不同,执行不同的任务. 比如:functiion jz(money){ //现金结账:验钞,找零 }     function jz(cardId,pwd){ //刷卡结 ...

  6. js的重载

    1.重载 //重载(个数不同,类型不同)function prop(){var firstP = document.getElementById("p");if(arguments ...

  7. js 方法重载

    function fun1(arm1) { alert(arm1); } function fun2(arm1, arm2) { alert(arm1 + "_" + arm2); ...

  8. js 函数重载

    简单定义:根据不同参数长度来实现让同一个函数,进行不同处理. function addMethod (obj, name, fun) { let old = obj[name] obj[name] = ...

  9. js函数的伪重载

    这也是今天写东西是遇到的一个问题,导致我联想起了函数重载的问题. 在javascript中是没有函数重载机制的,对于用惯了java开发的同学可能就表示吃惊了,我屮艸芔茻,函数 没有重载?那怎么搞?!! ...

随机推荐

  1. php – 通过curl从url获取JSON数据

    我试图通过curl连接从URL获取JSON数据.当我打开链接时:它显示{“version”:“N / A”,“success”:true,“status”:true}.现在,我希望获得以上内容. 到目 ...

  2. 6条shell小技巧,让脚本显得不再业余【转】

    如何能让自己的shell显得不那么业余?下面6点实践一定有用. 画外音:本篇文章源自Google的一篇实践,抽取了部分1分钟能读完的内容,加入了一些分析. 一.以下面的语句开场 set -o noun ...

  3. 一条SQL语句执行得很慢的原因有哪些?| MySQL高性能优化规范建议

    一条SQL语句执行得很慢的原因有哪些 https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247485185&idx=1&am ...

  4. 均值为1的独立指数随机Y1,Y2,组合成的Y=Y1-(Y2-1)^2/2 在Y>0的条件下也是指数随机变量

    均值为1的独立指数随机Y1,Y2,组合成的Y=Y1-(Y2-1)^2/2  在Y>0的条件下也是指数随机变量 另一个条件分布 13题有错误,应该是P{x<X<x+dx,y<Y& ...

  5. 从ASP.NET到ASP.NET Core差异变化

    MSDN原文:链接 ASP.NET Core项目为开发人员提供了针对.NET Core,.NET Framework2种实现方式,根据官网通告NETCORE3.0后将取消对.NET Framework ...

  6. eggjs异常捕获机制

    1. try catch捕获异步链中的方法 2. ctx.runInBackground(scope)捕获跳出异步链的方法 // 旧代码 class HomeController extends Co ...

  7. mysql索引本质

    一.索引帮助mysql高效获取数据排好序的数据结构. 二.索引存储位置:磁盘文件. 三.索引结构:二叉树.红黑树.hash.BTree.B+Tree .索引结构为了更快找到目标数据. 四.数据结构 4 ...

  8. django web问题

    django生命周期 1. 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端 请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者post,体现在url之中. ...

  9. EasyDSS高性能流媒体服务器开发RTMP直播同步输出HLS(m3u8)录像功能实现时移回放的方案

    EasyDSS商用流媒体服务器解决方案是由EasyDarwin开源团队原班人马开发的一套集流媒体点播.转码与管理.直播.录像.检索.时移回看于一体的一套完整的商用流媒体服务器解决方案,支持RTMP推流 ...

  10. darkflow测试和训练yolo

    转自 https://blog.csdn.net/u011961856/article/details/76582669参考自github:https://github.com/thtrieu/dar ...