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 相关文章推荐
dropdownlist之间的互相联动实现(显示与隐藏)
Nov 24 Javascript
JS时间选择器 兼容IE6,7,8,9
Jun 26 Javascript
js函数调用的方式
May 06 Javascript
深入探讨JavaScript、JQuery屏蔽网页鼠标右键菜单及禁止选择复制
Jun 10 Javascript
Javascript 学习笔记之 对象篇(二) : 原型对象
Jun 24 Javascript
jQuery on方法传递参数示例
Dec 09 Javascript
js时间戳转为日期格式的方法
Dec 28 Javascript
Node.js利用Net模块实现多人命令行聊天室的方法
Dec 23 Javascript
浅谈JS对象添加getter与setter的5种方法
Jun 09 Javascript
在小程序中使用Echart图表的示例代码
Aug 02 Javascript
Vue+Element-UI实现上传图片并压缩
Nov 26 Javascript
JS forEach跳出循环2种实现方法
Jun 24 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
使用array mutisort 实现按某字段对数据排序
2013/06/18 PHP
PHP实现过滤各种HTML标签
2015/05/17 PHP
PHP带节点操作的无限分类实现方法详解
2016/11/09 PHP
THINKPHP在添加数据的时候获取主键id的值方法
2017/04/03 PHP
JavaScript在IE中“意外地调用了方法或属性访问”
2008/11/19 Javascript
一个选择最快的服务器转向代码
2009/04/27 Javascript
IE和Firefox的Javascript兼容性总结[推荐收藏]
2011/10/19 Javascript
JS上传图片前的限制包括(jpg jpg gif及大小高宽)等
2012/12/19 Javascript
TextArea设置MaxLength属性最大输入值的js代码
2012/12/21 Javascript
关于JS管理作用域的问题
2013/04/10 Javascript
jQuery实现点击某个div打开层,点击其他div关闭层实例分析(阻止冒泡)
2016/11/18 Javascript
Javascript中字符串replace方法的第二个参数探究
2016/12/05 Javascript
js实现鼠标左右移动,图片也跟着移动效果
2017/01/25 Javascript
JS实现双击内容变为可编辑状态
2017/03/03 Javascript
JavaScript实现父子dom同时绑定两个点击事件,一个用捕获,一个用冒泡时执行顺序的方法
2017/03/30 Javascript
vue webuploader 文件上传组件开发
2017/09/23 Javascript
webpack搭建vue 项目的步骤
2017/12/27 Javascript
微信小程序全局变量功能与用法详解
2019/01/22 Javascript
原生js实现拖拽移动与缩放效果
2020/08/24 Javascript
使用jquery实现轮播图效果
2021/01/02 jQuery
python uuid模块使用实例
2015/04/08 Python
python 判断三个数字中的最大值实例代码
2019/07/24 Python
django正续或者倒序查库实例
2020/05/19 Python
Python3爬虫关于识别点触点选验证码的实例讲解
2020/07/30 Python
解决CSS3的opacity属性带来的层叠顺序问题
2016/05/09 HTML / CSS
naturalizer加拿大官网:美国娜然女鞋
2017/04/04 全球购物
西班牙宠物用品和食品网上商店:Tiendanimal
2019/06/06 全球购物
财政局长自荐信范文
2013/12/22 职场文书
给全校老师的建议书
2014/03/13 职场文书
安全承诺书范文
2014/03/26 职场文书
教师求职自荐信
2015/03/26 职场文书
2015年会计年终工作总结
2015/05/26 职场文书
赢在执行观后感
2015/06/16 职场文书
处罚决定书范文
2015/06/24 职场文书
python实现腾讯滑块验证码识别
2021/04/27 Python
golang生成vcf通讯录格式文件详情
2022/03/25 Golang