JS函数重载的解决方案


Posted in Javascript onMay 13, 2014

在面向对象的编程中,很多语言都支持函数重载,能根据函数传递的不同个数、类型的参数来做不同的操作,JS对它却不支持,需要我们额外做些小动作。


在JS的函数执行上下文中有一个名为arguments的有意思的变量,它以数组的形式存储了函数执行时传递过来的所有参数,即使函数定义没有定义这 么多个形参。还有一个特别之处就是跟Array类型相比,arguments变量有且只有一个length属性,Array的方法,例如push、pop 等,它并不具备,它只是一个“伪数组”:具有length属性,存储的数组能够用数组访问符[]来访问,并且是只读不可写。

一、对于不同个数参数的重载

这里应该很明白,直接用arguments函数的length属性来判断就可以了。

<script type="text/javascript">
function talk(msg,handler){ 
     var len = arguments.length; 
    //传递过来一个参数的时候执行 
    if(len==1){ 
    alert("Function say:"+msg); 
    } 
    //传递过来两个参数的时候执行 
    else if(len==2){ 
         handler(msg); 
     } 
} 
talk("demo"); 
talk("demo",function(w){alert("Handler say:"+w);}); 
</script>

二、对于不同类型的参数的重载 

对于JS这样一种动态类型的语言,这种变量声明的随意性淡化了严格的变量类型在开发人员脑子里的重要性(PS:同样是基于ECMA体系的,AS就引入 了变量声明的强制类型),很多意想不到的BUG其实都是由这种变量类型的自动转换造成的。其实JS提供了很准确的方法让我们来严格检测变量的类型,比较通 用的就是typeof方法和constructor属性。

1、typeof variable 返回变量类型

temp = "say"; //string 
temp = 1; //number 
temp = undefined; //undefined 
temp = null; //object 
temp = {}; //object 
temp = []; //object 
temp = true; //boolean 
temp = function (){} //function 
alert(typeof temp);

    通过上面的测试你可以看出来,对于null,Object,Array返回的都是object类型,而使用下面的方法就可以解决这个困扰。

2.constructor属性检测变量类型

    JS中每个对象都有constructor属性,它是用来引用构造此对象的函数,通过对这个引用的判断就可以检测变量类型了。

temp = "say"; 
temp.constructor==String; //true 
temp= {}; 
temp.constructor == Object;//true 
temp= []; 
temp.constructor == Array;//true

    通过上面的测试已经很容易的把Array和Object类型的变量区分开了。下面我们来对自定义的对象做个测试看看会发生什么。

//自定义对象 
function Ball(){} 
//实例化一个对象 
var basketBall = new Ball(); 
basketBall.constructor==Ball; //true

    这可以说明constructor属性对于自定义的对象一样适用。

在弄清楚了上面两个方法的适用以后再来回到JS函数重载的模拟上来,下面这个例子是根据参数类型来重载。

function talk(msg){ 
     var t = typeof msg; 
     if(t=="string"){ 
            alert("It's a string"); 
    } 
    else if(t=="number"){ 
            alert("It's a number"); 
     } 
} 
talk(10); //It's a string 
talk("demo"); //It's a number

附上一个很巧妙的严格检测参数类型和个数的函数:

//依据参数列表来严格地检查一个变量列表的类型 
function strict( types, args ) { 
     //确保参数的数目和类型核匹配 
     if ( types.length != args.length ) { 
            //如果长度不匹配,则抛出异常 
           throw "Invalid number of arguments. Expected " + types.length + ", received " + args.length + " instead."; 
    } 
    //遍历每一个参数,检查基类型 
    for ( var i = 0; i < args.length; i++ ) { 
          //如JavaScript某一项类型不匹配,则抛出异常 
          if ( args[i].constructor != types[i] ) { 
                throw "Invalid argument type. Expected " + types[i].name +", received " + args[i].constructor.name + " instead."; 
          } 
     } 
} 
//上述方法的使用 
function doFunction(id,name){ 
     //检测参数个数和类型 
     strict([Number,String],arguments); 
  .. 
}
Javascript 相关文章推荐
一个不错的应用,用于提交获取文章内容,不推荐用
Mar 03 Javascript
基于jQuery UI CSS Framework开发Widget的经验
Aug 21 Javascript
JavaScript通过setTimeout实时显示当前时间的方法
Apr 16 Javascript
JavaScript实现图片轮播的方法
Jul 31 Javascript
Js的Array数组对象详解
Feb 22 Javascript
Web前端开发之水印、图片验证码
Nov 27 Javascript
快速解决vue动态绑定多个class的官方实例语法无效的问题
Sep 05 Javascript
Vue中使用vux配置代码详解
Sep 16 Javascript
微信小程序云开发(数据库)详解
May 17 Javascript
Elasticsearch实现复合查询高亮结果功能
Sep 10 Javascript
微信小程序实现左滑删除效果
Nov 18 Javascript
element-ui封装一个Table模板组件的示例
Jan 04 Javascript
一个JS函数搞定网页标题(title)闪动效果
May 13 #Javascript
JS获得浏览器版本和操作系统版本的例子
May 13 #Javascript
当滚动条滚动到页面底部自动加载增加内容的js代码
May 13 #Javascript
js语法学习之判断一个对象是否为数组
May 13 #Javascript
js中定义一个变量并判断其是否为空的方法
May 13 #Javascript
jQuery 计算iframe 窗口大小的方法
May 13 #Javascript
js 调用百度地图api并在地图上进行打点添加标注
May 13 #Javascript
You might like
PHP中,文件上传
2006/12/06 PHP
libmysql.dll与php.ini是否真的要拷贝到c:\windows目录下呢
2010/03/15 PHP
apache和php之间协同工作的配置经验分享
2013/04/08 PHP
php格式化时间戳显示友好的时间实现思路及代码
2014/10/23 PHP
php注册登录系统简化版
2020/12/28 PHP
thinkPHP框架中执行事务的方法示例
2018/05/31 PHP
Javascript中获取出错代码所在文件及行数的代码
2010/09/23 Javascript
js 弹出菜单/窗口效果
2011/10/30 Javascript
jquery ajax的success回调函数中实现按钮置灰倒计时
2013/11/19 Javascript
页面刷新时记住滚动条的位置jquery代码
2014/06/17 Javascript
js实现兼容IE和FF的上下层的移动
2015/05/04 Javascript
jquery实现图片上传之前预览的方法
2015/07/11 Javascript
谈一谈JS消息机制和事件机制的理解
2016/04/14 Javascript
xmlplus组件设计系列之按钮(2)
2017/04/26 Javascript
jQuery实现广告条滚动效果
2017/08/22 jQuery
nodejs发送http请求时遇到404长时间未响应的解决方法
2017/12/10 NodeJs
vue实现微信分享朋友圈,发送朋友的示例讲解
2018/02/10 Javascript
小程序实现列表删除功能
2018/10/30 Javascript
javascript如何实现create方法
2019/11/04 Javascript
Python使用minidom读写xml的方法
2015/06/03 Python
python实现两个一维列表合并成一个二维列表
2019/12/02 Python
python 数据分析实现长宽格式的转换
2020/05/18 Python
HTML5印章绘制电子签章图片(中文英文椭圆章、中文英文椭圆印章)
2019/06/03 HTML / CSS
澳大利亚票务和娱乐市场领导者:Ticketmaster
2017/03/03 全球购物
健身场所或家用健身设备:Life Fitness
2017/11/01 全球购物
网络教育自我鉴定
2014/02/04 职场文书
2014年端午节活动方案
2014/03/11 职场文书
活动总结怎么写
2014/04/28 职场文书
四风问题对照检查材料整改措施
2014/09/27 职场文书
2015年敬老院工作总结
2015/05/18 职场文书
感动中国何玥观后感
2015/06/02 职场文书
安全学习心得体会范文
2016/01/18 职场文书
幽默口才训练经典句子(48句)
2019/08/19 职场文书
使用HTML+Css+transform实现3D导航栏的示例代码
2021/03/31 HTML / CSS
手把手教你怎么用Python实现zip文件密码的破解
2021/05/27 Python
Flask response响应的具体使用
2021/07/15 Python