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 相关文章推荐
基于jquery的大众点评,分类导航实现代码
Aug 23 Javascript
深入理解Javascript里的依赖注入
Mar 19 Javascript
javascript实现checkbox全选的代码
Apr 30 Javascript
浅谈JavaScript字符串与数组
Jun 03 Javascript
Jquery Mobile 自定义按钮图标
Nov 18 Javascript
bootstrap输入框组代码分享
Jun 07 Javascript
js监听input输入框值的实时变化实例
Jan 26 Javascript
Express之get,pos请求参数的获取
May 02 Javascript
AngularJS获取json数据的方法详解
May 27 Javascript
利用webstrom调试Vue.js单页面程序的方法教程
Jun 06 Javascript
vue实现图片懒加载的方法分析
Feb 05 Javascript
原生js实现简单轮播图
Oct 26 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 cron中的批处理
2008/09/16 PHP
PHP中将网页导出为Word文档的代码
2012/05/25 PHP
php利用新浪接口查询ip获取地理位置示例
2014/01/20 PHP
php使用pdo连接报错Connection failed SQLSTATE的解决方法
2014/12/15 PHP
微信公众平台实现获取用户OpenID的方法
2015/04/15 PHP
PHP使用逆波兰式计算工资的方法
2015/07/29 PHP
thinkphp微信开发(消息加密解密)
2015/12/02 PHP
thinkphp3.x中变量的获取和过滤方法详解
2016/05/20 PHP
PHP如何实现跨域
2016/05/30 PHP
JS在IE和FireFox之间常用函数的区别小结
2010/03/12 Javascript
jQuery如何防止这种冒泡事件发生
2015/02/27 Javascript
javascript实现日期时间动态显示示例代码
2015/09/08 Javascript
JS实现超简单的鼠标拖动效果
2015/11/02 Javascript
如何利用AngularJS打造一款简单Web应用
2015/12/05 Javascript
javascript实现标签切换代码示例
2016/05/22 Javascript
Javascript中函数名.length属性用法分析(对比arguments.length)
2016/09/16 Javascript
AnjularJS中$scope和$rootScope的区别小结
2016/09/18 Javascript
JS排序之选择排序详解
2017/04/08 Javascript
详解axios在node.js中的post使用
2017/04/27 Javascript
微信小程序实现点击图片放大预览
2019/10/21 Javascript
谈谈JavaScript令人迷惑的==与+
2020/08/31 Javascript
Python复制目录结构脚本代码分享
2015/03/06 Python
Python通过poll实现异步IO的方法
2015/06/04 Python
Python Paramiko模块的安装与使用详解
2016/11/18 Python
详细解读tornado协程(coroutine)原理
2018/01/15 Python
Python3 itchat实现微信定时发送群消息的实例代码
2019/07/12 Python
pandas DataFrame行或列的删除方法的实现示例
2019/08/02 Python
python+Django实现防止SQL注入的办法
2019/10/31 Python
python判断链表是否有环的实例代码
2020/01/31 Python
如何基于Python和Flask编写Prometheus监控
2020/11/25 Python
PacSun官网:加州生活方式服装、鞋子和配饰
2018/03/10 全球购物
NICKIS.com荷兰:设计师儿童时装
2020/01/08 全球购物
求职信格式要求
2014/05/23 职场文书
党的群众路线教育实践活动对照检查材料(四风)
2014/09/27 职场文书
2016年优秀少先队辅导员事迹材料
2016/02/26 职场文书
详解nodejs内置模块
2021/05/06 NodeJs