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 相关文章推荐
Extjs学习笔记之五 一个小细节renderTo和applyTo的区别
Jan 07 Javascript
window.onbeforeunload方法在IE下无法正常工作的解决办法
Jan 23 Javascript
JQuery index()方法使用代码
Jun 02 Javascript
使用cluster 将自己的Node服务器扩展为多线程服务器
Nov 10 Javascript
javascript获取当前的时间戳的方法汇总
Jul 26 Javascript
js实现div模拟模态对话框展现URL内容
May 27 Javascript
Javascript如何判断数据类型和数组类型
Jun 22 Javascript
正则表达式,替换所有HTML标签的简单实例
Nov 28 Javascript
jQuery特殊符号转义的实现
Nov 30 Javascript
深入理解Node.js中通用基础设计模式
Sep 19 Javascript
vue更改数组中的值实例代码详解
Feb 07 Javascript
AngularJs的$http发送POST请求,php无法接收Post的数据问题及解决方案
Aug 13 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输出XML到页面的3种方法详解
2013/06/06 PHP
Joomla简单判断用户是否登录的方法
2016/05/04 PHP
ThinkPHP实现生成和校验验证码功能
2017/04/28 PHP
PHP中十六进制颜色与RGB颜色值互转的方法
2019/03/18 PHP
基于PHP实现解密或加密Cloudflar邮箱保护
2020/06/24 PHP
推荐:极酷右键菜单
2006/11/29 Javascript
Javascript的IE和Firefox兼容性汇编(zz)
2007/02/02 Javascript
JavaScript中的prototype使用说明
2010/04/13 Javascript
ExtJs纵坐标值重复问题的解决方法
2014/02/27 Javascript
在Node.js中实现文件复制的方法和实例
2014/06/05 Javascript
JavaScript自定义数组排序方法
2015/02/12 Javascript
使用jquery清空、复位整个输入域
2015/04/02 Javascript
jQuery学习心得总结(必看篇)
2016/06/10 Javascript
使用Ajax与服务器(JSON)通信实例
2016/11/04 Javascript
移动开发之自适应手机屏幕宽度
2016/11/23 Javascript
利用select实现年月日三级联动的日期选择效果【推荐】
2016/12/13 Javascript
Vue单文件组件的如何使用方式介绍
2017/07/28 Javascript
微信小程序自定义模态对话框实例详解
2017/08/16 Javascript
详解10分钟学会vue滚动行为
2017/09/21 Javascript
Node.js中读取TXT文件内容fs.readFile()用法
2018/10/10 Javascript
使用react render props实现倒计时的示例代码
2018/12/06 Javascript
Element-UI中关于table表格的那些骚操作(小结)
2019/08/15 Javascript
vue 使用v-for进行循环的实例代码详解
2020/02/19 Javascript
Python实现二分法算法实例
2015/02/02 Python
Python中的左斜杠、右斜杠(正斜杠和反斜杠)
2016/08/30 Python
python3使用pyqt5制作一个超简单浏览器的实例
2017/10/19 Python
python实现决策树ID3算法的示例代码
2018/05/30 Python
浅谈python的深浅拷贝以及fromkeys的用法
2019/03/08 Python
Pandas+Matplotlib 箱式图异常值分析示例
2019/12/09 Python
css3实现二维码扫描特效的示例
2020/10/29 HTML / CSS
yy生日主持词
2014/03/20 职场文书
学校志愿者活动总结
2014/06/27 职场文书
公司禁烟通知
2015/04/23 职场文书
入党群众意见范文
2015/06/02 职场文书
汽车修理厂管理制度
2015/08/05 职场文书
MySQL 如何设计统计数据表
2021/06/15 MySQL