JavaScript函数重载操作实例浅析


Posted in Javascript onMay 02, 2020

本文实例讲述了JavaScript函数重载操作。分享给大家供大家参考,具体如下:

上个星期四下午,接到了网易的视频面试(前端实习生第二轮技术面试)。面了一个多小时,自我感觉面试得很糟糕的,因为问到的很多问题都很难,根本回答不上来。不过那天晚上,还是很惊喜的接到了HR面电话。现在HR面试的结果还没有出来,听说要等到下周二才出,所以再好好等几天哈。

前面说了这多的废话,现在是时候和伙伴们分享一下面试干货哈。因为二面问到的内容还挺多的,所以这里就不全部列举出来了。这里只讨论一下函数的重载。

下面是面试时的对话,“面”指面试官,“我”就是我~

面:你能说说JS怎么实现函数的重载吗?
我:因为JS的参数是可变长度的,是没有重载的!也是没必要用重载的!
面:怎么没必要使用重载?你先告诉什么是重载?
我: 重载就是一组具有相同名字、不同参数列表的函数(方法)。
面:对的,那为什么你还说JS没有重载,也没必要使用重载呢?

我当时一脸懵逼了,因为不知道面试官到底是想要考我什么,因为我记得《JS高级程序设计》里是提到过函数是没有重载的啊(后来查了一下,在第三版的66页,亲们可以自己翻开书本看看),但是现在面试官不同意我的回答啊,就是说在他看来,JS是有重载的,我不能坚持说没有重载啊。所以我就往重载的概念方向静静的思考了片刻,然后想到了使用arguments对象进行判断。于是:
我:我觉得,如果JS函数需要实现重载的话,可以根据arguments对象的length值进行判断。
面: 你可以写个例子出来给我看吗?
然后,我就在输入框里面写了如下的代码:

function overLoading() {
// 根据arguments.length,对不同的值进行不同的操作

switch(arguments.length) {


case 0:



/*操作1的代码写在这里*/



break;


case 1:



/*操作2的代码写在这里*/



break;


case 2:



/*操作3的代码写在这里*/
 




//后面还有很多的case......
}
 
}

我把代码发给了面试官。

面:对,这就是重载的一种实现的方法!不过你能不能想出一个更好的方法呢?
我: 暂时就想到这一种方法了。

好吧,跟面试官的对话就写这么多了。他说问我能不能想出一个更好的办法,意味着肯定还有其他我不知道的方法。所以,后来就开始翻书本查找。哈哈,终于在JQuery之父John Resig写的《secrets of the JavaScript ninja》找到了一个绝佳巧妙的方法!那种方法充分的利用了闭包的特性!

在介绍这个方法之前,我们先来看看外国人名字组成哈,比如,John Resig,John是first-name,Resig是last-name,就相当于我们的姓名由姓和名组成一样。

我们现在有这样的一个需求,有一个people对象,里面存着一些人名,如下:

var people = {
 values: ["Dean Edwards", "Sam Stephenson", "Alex Russell", "Dean Tom"]
};

我们希望people对象拥有一个find方法,当不传任何参数时,就会把people.values里面的所有元素返回来;当传一个参数时,就把first-name跟这个参数匹配的元素返回来;当传两个参数时,则把first-name和last-name都匹配的才返回来。因为find方法是根据参数的个数不同而执行不同的操作的,所以,我们希望有一个addMethod方法,能够如下的为people添加find的重载:

addMethod(people, "find", function() {}); /*不传参*/
addMethod(people, "find", function(a) {}); /*传一个*/
addMethod(people, "find", function(a, b) {}); /*传两个*/

这时候问题来了,这个全局的addMethod方法该怎么实现呢?John Resig的实现方法如下,代码不长,但是非常的巧妙:

function addMethod(object, name, fn) {
var old = object[name]; //把前一次添加的方法存在一个临时变量old里面

object[name] = function() { // 重写了object[name]的方法


// 如果调用object[name]方法时,传入的参数个数跟预期的一致,则直接调用


if(fn.length === arguments.length) {



return fn.apply(this, arguments);


// 否则,判断old是否是函数,如果是,就调用old


} else if(typeof old === "function") {



return old.apply(this, arguments);


}

}
}

现在,我们一起来分析一个这个addMethod函数,它接收3个参数,第一个为要绑定方法的对象,第二个为绑定的方法名称,第三个为需要绑定的方法(一个匿名函数)。函数体的的分析已经在注释里面了。

OK,现在这个addMethod方法已经实现了,我们接下来就实现people.find的重载啦!全部代码如下:

//addMethod
function addMethod(object, name, fn) {
var old = object[name];

object[name] = function() {


if(fn.length === arguments.length) {



return fn.apply(this, arguments);


} else if(typeof old === "function") {



return old.apply(this, arguments);


}

}
}
var people = {

values: ["Dean Edwards", "Alex Russell", "Dean Tom"]
};
 
/* 下面开始通过addMethod来实现对people.find方法的重载 */
 
// 不传参数时,返回peopld.values里面的所有元素
addMethod(people, "find", function() {

return this.values;
});
 
// 传一个参数时,按first-name的匹配进行返回
addMethod(people, "find", function(firstName) {

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;
});
 
// 传两个参数时,返回first-name和last-name都匹配的元素
addMethod(people, "find", function(firstName, lastName) {

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()); //["Dean Edwards", "Alex Russell", "Dean Tom"]
console.log(people.find("Dean")); //["Dean Edwards", "Dean Tom"]
console.log(people.find("Dean Edwards")); //["Dean Edwards"]

好啦,实现JS函数重载就写这么多啦,如果亲们有更好的实现方法,欢迎评论交流哈~

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.3water.com/code/HtmlJsRun测试上述代码运行效果。

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
jQuery中文入门指南,翻译加实例,jQuery的起点教程
Jan 13 Javascript
Jquery刷新页面背景图片随机变换的实现方法
Mar 15 Javascript
javascript的内存管理详解
Aug 07 Javascript
jquery数组封装使用方法分享(jquery数组遍历)
Mar 25 Javascript
JS在一定时间内跳转页面及各种刷新页面的实现方法
May 26 Javascript
Jquery Easyui菜单组件Menu使用详解(15)
Dec 18 Javascript
Bootstrap表单简单实现代码
Mar 06 Javascript
js 公式编辑器 - 自定义匹配规则 - 带提示下拉框 - 动态获取光标像素坐标
Jan 04 Javascript
vue移动端监听滚动条高度的实现方法
Sep 03 Javascript
35个最好用的Vue开源库(史上最全)
Jan 03 Javascript
JS实现获取当前所在周的周六、周日示例分析
May 11 Javascript
vue打开新窗口并实现传参的图文实例
Mar 04 Vue.js
有趣的JavaScript隐式类型转换操作实例分析
May 02 #Javascript
react-router-dom 嵌套路由的实现
May 02 #Javascript
在react中使用vue的状态管理的方法示例
May 02 #Javascript
JS表单验证插件之数据与逻辑分离操作实例分析【策略模式】
May 01 #Javascript
javascript实现的图片预览和上传功能示例【兼容IE 9】
May 01 #Javascript
jQuery实现的移动端图片缩放功能组件示例
May 01 #jQuery
jQuery实现移动端图片上传预览组件的方法分析
May 01 #jQuery
You might like
推荐php模板技术[转]
2007/01/04 PHP
PHP 开发环境配置(Zend Server安装)
2010/04/28 PHP
phplist及phpmailer(组合使用)通过gmail发送邮件的配置方法
2016/03/30 PHP
Swoole扩展的6种模式深入详解
2021/03/04 PHP
jQuery之浮动窗口实现代码(两种方法)
2010/09/08 Javascript
javascript跟随滚动效果插件代码(javascript Follow Plugin)
2013/08/03 Javascript
顶部缓冲下拉菜单导航特效的JS代码
2013/08/27 Javascript
javascript 实现 原路返回
2015/01/21 Javascript
详解JavaScript的Polymer框架中的通知交互
2015/07/29 Javascript
基于Css3和JQuery实现打字机效果
2015/08/11 Javascript
JQuery通过AJAX从后台获取信息显示在表格上并支持行选中
2015/09/15 Javascript
跟我学习javascript的prototype使用注意事项
2015/11/17 Javascript
AngularJS 面试题集锦
2016/09/06 Javascript
微信小程序授权获取用户详细信息openid的实例详解
2017/09/20 Javascript
如何优雅的在一台vps(云主机)上面部署vue+mongodb+express项目
2019/01/20 Javascript
vue中axios请求的封装实例代码
2019/03/23 Javascript
WebSocket的简单介绍及应用
2019/05/23 Javascript
vue cli 3.0通用打包配置代码,不分一二级目录
2020/09/02 Javascript
django开发教程之利用缓存文件进行页面缓存的方法
2017/11/10 Python
python实现简单的单变量线性回归方法
2018/11/08 Python
使用python将多个excel文件合并到同一个文件的方法
2019/07/09 Python
python basemap 画出经纬度并标定的实例
2019/07/09 Python
Python定时任务工具之APScheduler使用方式
2019/07/24 Python
Python 批量刷博客园访问量脚本过程解析
2019/08/30 Python
python实现俄罗斯方块游戏(改进版)
2020/03/13 Python
美国领先的家庭健康检测试剂盒提供商:LetsGetChecked
2019/03/18 全球购物
美国最大的在线生存商店:Survival Frog
2020/12/13 全球购物
Nike俄罗斯官方网站:Nike RU
2021/03/05 全球购物
大学生个人自荐信样本
2014/03/02 职场文书
有关九一八事变的演讲稿
2014/09/14 职场文书
2015年入党积极分子评语
2015/03/26 职场文书
房地产销售助理岗位职责
2015/04/14 职场文书
大学生干部培训心得体会
2016/01/06 职场文书
小学毕业教师寄语
2019/06/21 职场文书
七年级之家长会发言稿范文
2019/09/04 职场文书
OpenCV全景图像拼接的实现示例
2021/06/05 Python