JS实现重载

在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(); //0
        arr.find(1);  //1
        arr.find(1, 2);  //2
        arr.find(1, 2, 3); //Uncaught TypeError: Cannot read property ‘apply‘ of undefined

/**第一次进行绑定时,先赋值old,因为attr.find并没有被创建,所以old=undefined。然后为arr对象find属性创建一个匿名方法,这个匿名方法fn.length=1。
第二次进行绑定时,将old对象指向第一次创建的匿名方法,然后会将arr对象find属性指向到当前创建的匿名方法,因为old指向上个方法的引用,这就会造成上个方法不会被释放。
第三次也是一样的步骤,保证第二次绑定的方法不会被释放。
重载方法的执行,像一个链条一样,先从最后绑定的方法内部开始寻找 方法定义的参数个数和传入的个数是否匹配,如果匹配则返回当前的传入的匿名函数,否则继续向上查找,直到找到为止。
如果最后没有找到结果,当前程序会报错,因为第一次绑定方法时,old对象是一个undefined
**/

绑定阶段

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

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

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

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

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

时间: 2024-08-26 10:32:03

JS实现重载的相关文章

JS函数重载解决方案

JS的函数定义可以指定形式参数名称,多多少少我们会以为js至少可以支持参数个数不同的方法重载,然而遗憾的是这仅仅是一个假象,js所有的参数都是以arguments传递过去的,这个参数类似于数组,在函数调用的时候,所有的实参都是保存在了这个数据结构里面,我们定义函数的时候所指定的形式参数其实是为这个数据结构里面的数据定义一个快捷的访问方式.也就是说js所有的函数都是支持无限个参数的,加上数据类型是弱类型,那么JS的函数除了名称就真的没有方法区别了? 办法总是有的,我们可以利用JavaScript中

Js里重载问题

JS里是否存在重载? 我们知道JS和Java很像,Java是有重载的,那么JS里有吗? 答案是没有的 重载就是函数(方法)名一样,参数列表不同,同命不同参称之为重载 在js里如果有同命不同参的函数,则后写的函数覆盖前面的函数(html从上到下解析顺序),也就是多个同名函数,只有一个最后一个起作用. 模拟重载 js里虽然没有重载,但是我们可以模拟重载 说明 模拟重载需要用到arguments argument是类数组对象 属性 length 获取arguments对象的长度 callee 引用当前

js 方法重载

function fun1(arm1) { alert(arm1); } function fun2(arm1, arm2) { alert(arm1 + "_" + arm2); } function fun(arm1, arm2) { if (arguments.length == 1) { fun1("我一个人啦"); } else { fun2("我一个人啦",",终于来个伴了"); } } $(function ()

js的DOM对象

1.js的Array对象           ** 创建数组(三种)                          - var arr1 = [1,2,3];                          - var arr2 = new Array(3); //长度是3                          - var arr3 = new Array(1,2,3); //数组中的元素是1 2 3 - var arr = []; //创建一个空数组 ** 属性:length

JS定义函数

定义函数有三种方式:1,function fun()这种叫函数申明;2,var fun=function()这种叫函数表达式;3,var fun=new Function()也叫函数表达式.在同一个执行环境中,函数申明不管是在什么位置,都会被提升至代码的最前面,即便前面是函数表达式,这个是js的规则. 例题: function fun (){ alert(0); } fun(); var fun = function (){ alert(1); } fun(); var fun =functio

<JS高级程序设计3>_PART3

1.ECMAScript中所有数都以IEEE-754 64位格式存储,但位操作符不直接操作64位的值.是先64位转换成32位的整数,再操作,得到结果再转成64位. 2.首位是符号位.之后的31位代表整数的值. 3.用toString(2)打印二进制,得到的是被处理过的二进制. 4.按位非(NOT)~,数转成二进制,取反.相当于把操作数先变负再-1; 5.按位与(AND)&,两个数的二进制,有一个0结果就是0,两个都是1才为1. 6.按位或(OR)|,有一个1结果为1,都是0才为0. 7.按位异或

JavaWeb基础—JS学习小结

JavaScript是一种运行在浏览器中的解释型的编程语言一.简介js:javascript是基于对象[哪些基本对象呢]和和事件驱动[哪些主要事件呢]的语言,应用在客户端(注意与面向对象的区分) js的三大特点: 交互性:信息的动态交互 安全性:不能访问本地磁盘的文件 跨平台性:能支持js的浏览器都能运行 JavaScript 对大小写敏感 与java的区别:(只是长得像而已,雷锋&雷峰塔)  1.不同公司开发的语言,java:Oracl js:网景公司 2.java:面向对象 js:基于对象(

animate动画方法封装:原生JS实现

1 /** 2 * Created by guoyongfeng on 2014/7/7. 3 * @Author guoyongfeng 4 * @Date 2014-07-07 5 * @Version 1.0.0 6 * @update 2014-07-07 7 * @described tween动画库函数封装 8 * 9 */ 10 define('animate/0.0.1', function(){ 11 /** 12 * 13 */ 14 return function(ele,

浅谈JavaScript函数重载

上个星期四下午,接到了网易的视频面试(前端实习生第二轮技术面试).面了一个多小时,自我感觉面试得很糟糕的,因为问到的很多问题都很难,根本回答不上来.不过那天晚上,还是很惊喜的接到了HR面电话.现在HR面试的结果还没有出来,听说要等到下周二才出,所以再好好等几天哈. 前面说了这多的废话,现在是时候和伙伴们分享一下面试干货哈.因为二面问到的内容还挺多的,所以这里就不全部列举出来了.这里只讨论一下函数的重载. 下面是面试时的对话,“面”指面试官,“我”就是我~ 面:你能说说JS怎么实现函数的重载吗?