摘要:后续说完上面的再对比下面的理解,会更深入的理解原型与原型链这里是对象拥有了这样的方法,而不是,是继承区别于方法直接作用于原型上例子的实现
所谓重载,就是一组相同的函数名,有不同个数的参数,在使用时调用一个函数名,传入不同参数,根据你的参数个数,来决定使用不同的函数!但是我们知道js中是没有重载的,因为后定义的函数会覆盖前面的同名函数,但是我们又想实现函数重载该怎么办呢?
第1种方法:
这种方法比较简单,给一个思路,大家肯定都能理解,就是函数内部用switch语句,根据传入参数的个数调用不同的case语句,从而功能上达到重载的效果。
这种方法简单粗暴
第二种方法
function method(obj,name,fnc){ var old = obj[name]; console.log(old instanceof Function); obj[name] = function(){ console.log(arguments.length+" "+fnc.length); if(arguments.length === fnc.length){ return fnc.apply(this,arguments); }else if(typeof old === "function"){ return old.apply(this,arguments); } } } var people = { values:["Zhang san","Li si"] }; method(people,"find",function(){ console.log("无参数"); return this.values; }) method(people,"find",function(firstname){ console.log("一个参数"); var ret = []; for(var i = 0;i < this.values.length;i++){ if(this.values[i].indexOf(firstname) === 0){ ret.push(this.values[i]) } } return ret; }) method(people,"find",function(firstname,lastname){ console.log("两个参数"); var ret = []; for(var i = 0;i < this.values.length;i++){ if(this.values[i] == firstname + " " + lastname){ ret.push(this.values[i]) } } return ret; }) console.log(people.find()); console.log(people.find("Zhang"));
实现过程:我们看一下上面这段代码,最重要的是method方法的定义:这个方法中最重要的一点就是这个old,这个old真的很巧妙。它的作用相当于一个指针,指向上一次被调用的method函数,这样说可能有点不太懂,我们根据代码来说,js的解析顺序从上到下为。
1.解析method(先不管里面的东西)
2.method(people,"find",function() 执行这句的时候,它就回去执行上面定义的方法,然后此时old的值为空,因为你还没有定义过这个函数,所以它此时是undefined,然后继续执行,这是我们才定义 obj[name] = function(),然后js解析的时候发现返回了fnc函数,更重要的是fnc函数里面还调用了method里面的变量,这不就是闭包了,因为fnc函数的实现是在调用时候才会去实现,所以js就想,这我执行完也不能删除啊,要不外面那个用啥,就留着吧先(此处用call函数改变了fnc函数内部的this指向)
3.好了第一次method的使用结束了,开始了第二句,method(people,"find",function(firstname) 然后这次使用的时候,又要执行old = obj[name]此时的old是什么,是函数了,因为上一条语句定义过了,而且没有删除,那我这次的old实际上指向的是上次定义的方法,它起的作用好像一个指针,指向了上一次定义的 obj[name]。然后继续往下解析,又是闭包,还得留着。
4.第三此的method调用开始了,同理old指向的是上次定义的 obj[name] 同样也还是闭包,还得留着。
5.到这里,内存中实际上有三个 obj[name],因为三次method的内存都没有删除,这是不是实现了三个函数共存,同时还可以用old将它们联系起来是不是很巧妙
6.我们 people.find() 的时候,就会最先调用最后一次调用method时定义的function,如果参数个数相同 也就是 arguments.length === fnc.length 那么就执行就好了,也不用找别的函数了,如果不相同的话,那就得用到old了 return old.apply(this,arguments); old指向的是上次method调用时定义的函数,所以我们就去上一次的找,如果找到了,继续执行 arguments.length === fnc.length 如果找不到,再次调用old 继续向上找,只要你定义过,肯定能找到的,对吧!
总结:运用闭包的原理使三个函数共存于内存中,old相当于一个指针,指向上一次定义的function,每次调用的时候,决定是否需要寻找。
后续:说完上面的再对比下面的理解,会更深入的理解原型与原型链
var array=[] addMethod(array,"sub0",function(){ return 0; }) addMethod(array,"sub0",function(prefix){ console.log("prefix===>",prefix); return prefix[0]; }) array.sub0([1,2,3,5]) //这里是array对象拥有了sub0这样的方法,而不是Array,addMethod是继承 // 区别于方法直接作用于原型上 //例子 String的 startsWith 实现 function addstartsWithToString(){ if (typeof String.prototype.startsWith1 != "function" ) { String.prototype.startsWith1 = function(subString){ return this.slice(0,subString.length)==subString } } } addstartsWithToString(); "120000".startsWith1("1")
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/108421.html
摘要:说明中没有真正意义上的函数重载。先看第一种办法,通过对象来实现对象,是函数内部的一个类数组对象,它里面保存着调用函数时,传递给函数的所有参数。 说明 JavaScript 中没有真正意义上的函数重载。 函数重载 函数名相同,函数的参数列表不同(包括参数个数和参数类型),根据参数的不同去执行不同的操作。 我们举个例子看看 function overload(a){ conso...
摘要:使用与实现了一个比较简单但功能齐全的增删改查功能的后台管理页面,虽然只是一个页面,但麻雀虽小五脏俱全,常用的功能都用到了,本例用原生的与配合使用,不考虑的重构性及打包,该例子零耦合,开箱即用。相关文章实现双击内容变为可编辑状态 使用jquery与bootstrap实现了一个比较简单但功能齐全的增删改查功能的后台管理页面,虽然只是一个CRUD页面,但麻雀虽小五脏俱全,JS常用的功能都用到...
摘要:类型声明中的函数定义,需要声明参数和返回值的类型。其中隐藏有一个点类型推断,箭头函数没有声明返回值类型,这里编译器不会报错,因为它可以推断出返回值类型。 引言 TypeScript中的函数和JavaScript中的函数,和其他特性相比,是相差不大的。 这里会补充一点进阶知识。 函数相关的知识点 下面列举一些TypeScript中函数相关的知识点。 类型声明 TypeScript中的函...
阅读 1422·2021-11-24 09:39
阅读 3579·2021-09-29 09:47
阅读 1539·2021-09-29 09:34
阅读 3049·2021-09-10 10:51
阅读 2512·2019-08-30 15:54
阅读 3198·2019-08-30 15:54
阅读 852·2019-08-30 11:07
阅读 988·2019-08-29 18:36