序大家好,我是林三鑫。用最通俗易懂的语言解释最难的知识点是我的座右铭。基础是进阶的前提是我的初衷。今天给大家说一道题,是一道网易的面试题。某同学:“如何实现JS重载?”我:“JS有重载吗?TS不就只有吗?”是网易的面试题。”我说:“好吧,让我考虑一下!”什么是超载?第一次看到重载这个词是在学习Java的时候。一直以为JavaScript没有重载,直到TypeScript的出现,所以我一直认为JavaScript没有重载,只有TypeScript,但现在看来我错了。我理解的重载是:同一个函数,不同的参数个数,执行不同的代码,例如:/**Overloading*/functionfn(name){console.log(`Iam${name}`)}functionfn(name,age){console.log(`我今年${name},${age}岁`)}functionfn(name,age,sport){console.log(`我是${name},今年${age}岁,喜欢运动${sport}`)}/**理想成绩*/fn('林三鑫')//我是林三鑫fn('林三鑫',18)//我是林三鑫,今年18岁fn('林三鑫',18,'打篮球')//我是林三鑫,今年18岁,喜欢打篮球但是直接用JavaScript这样写肯定不行。我们来看看上面代码的实际执行结果。可以看到fn的最后一个定义覆盖了前两个,所以并没有实现重载的效果。我是林三鑫,今年未定义,喜欢运动未定义我是林三鑫,今年18岁,喜欢运动未定义我是林三鑫,今年18岁,喜欢运动是打篮球我实践其实是,我想达到理想的重载结果,我还是有办法的,我可以直接写一个fn函数,在这个函数里面判断arguments类数组的长度,执行不同的代码,然后效果可以完成重载functionfn(){switch(arguments.length){case1:var[name]=argumentsconsole.log(`Iam${name}`)break;case2:var[name,age]=argumentsconsole.log(`我是${name},今年${age}岁`)break;case3:var[name,age,sport]=argumentsconsole.log(`我今年${name},${age}岁,我最喜欢的运动是${sport}`)break;}}/**实现效果*/fn('林三鑫')//我是林三鑫fn('林三鑫',18)//我是林三鑫,我今年18岁fn('林三鑫',18,'打篮球')//我是林三鑫,我今年18岁,我喜欢打运动篮球,但是同学说网易的面试官好像觉得这个可以做,但是如果有更好的方法做,我对高端的做法一头雾水。在网上查找资料后,找到了一个比较高端的做法,可以使用闭包来达到重载的效果。这个方法是JQuery之父JohnResig写的《secrets of the JavaScript ninja》里的。这个方法充分利用了闭包的特性!functionaddMethod(object,name,fn){varold=object[name];//将之前添加的方法存储在一个临时变量中oldobject[name]=function(){//重写object[name]的方法//如果调用object[时传入的参数个数与期望的个数一致name]方法,然后直接调用它if(fn.length===arguments.length){returnfn.apply(this,arguments);//否则判断old是否为函数,如果是则调用old}elseif(typeofold==="function"){returnold.apply(this,arguments);}}}addMethod(window,'fn',(name)=>console.log(`我是${name}`))addMethod(window,'fn',(name,age)=>console.log(`我是${name},今年${age}岁`))addMethod(window,'fn',(name,age,sport)=>console.log(`我是${name},${age}今年岁了,喜欢运动${sport}`))/**实现效果*/window.fn('林三鑫')//我是林三鑫window.fn('林三鑫',18)//我是林三鑫,18岁window.fn('林三鑫',18,'打篮球')//我是林三鑫,我今年18岁,喜欢运动,喜欢打篮球林三鑫哈哈。或者你也可以加入我的摸鱼群,一起努力学习,我会定期模拟面试,简历指导,答疑解惑,互相学习,共同进步!!参考资料浅谈JavaScript函数重载
