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中获得$.ajax()事件返回的值并添加事件的方法
Apr 15 Javascript
js下判断 iframe 是否加载完成的完美方法
Oct 26 Javascript
jQuery .attr()和.removeAttr()方法操作元素属性示例
Jul 16 Javascript
jQuery实现向下滑出的二级菜单效果实例
Aug 22 Javascript
js实现动态创建的元素绑定事件
Jul 19 Javascript
jQuery实现可移动选项的左右下拉列表示例
Dec 26 Javascript
jQuery时间验证和转换为标准格式的时间格式
Mar 06 Javascript
vue axios用法教程详解
Jul 23 Javascript
Angular5升级RxJS到5.5.3报错:EmptyError: no elements in sequence的解决方法
Apr 09 Javascript
vue项目前端埋点的实现
Mar 06 Javascript
vue 点击展开显示更多(点击收起部分隐藏)
Apr 09 Javascript
使用konva和vue-konva库实现拖拽滑块验证功能
Apr 27 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
检测png图片是否完整的php代码
2010/09/06 PHP
基于PHPExcel的常用方法总结
2013/06/13 PHP
WordPress导航菜单的滚动和淡入淡出效果的实现要点
2015/12/14 PHP
浅谈PHP值mysql操作类
2016/06/29 PHP
功能强大的PHP发邮件类
2016/08/29 PHP
颜色选择器 Color Picker,IE,Firefox,Opera,Safar
2010/11/25 Javascript
JavaScript-RegExp对象只能使用一次问题解决方法
2014/06/23 Javascript
跟我学习javascript的函数和函数表达式
2015/11/16 Javascript
Bootstrap3.0建站教程(一)之bootstrap表单元素排版
2016/06/01 Javascript
JavaScript中apply方法的应用技巧小结
2016/09/29 Javascript
Bootstrap基本样式学习笔记之表单(3)
2016/12/07 Javascript
jQuery实现优雅的弹窗效果(6)
2017/02/08 Javascript
node.js 抓取代理ip实例代码
2017/04/30 Javascript
JS字符串去除连续或全部重复字符的实例
2018/03/08 Javascript
详解webpack运行Babel教程
2018/06/13 Javascript
对Vue- 动态元素属性及v-bind和v-model的区别详解
2018/08/27 Javascript
ES6中let 和 const 的新特性
2018/09/03 Javascript
详解vue中router-link标签所必备了解的属性
2019/04/15 Javascript
layui的面包屑或者表单不显示的解决方法
2019/09/05 Javascript
Vue数字输入框组件使用方法详解
2020/02/10 Javascript
JavaScript实现Tab标签页切换的最简便方式(4种)
2020/06/28 Javascript
vue-simple-uploader上传成功之后的response获取代码
2020/09/07 Javascript
浅析VUE防抖与节流
2020/11/24 Vue.js
[01:44]《为梦想出发》—联想杯DOTA2完美世界全国高校联赛
2015/09/30 DOTA
Python中使用glob和rmtree删除目录子目录及所有文件的例子
2014/11/21 Python
使用python实现正则匹配检索远端FTP目录下的文件
2015/03/25 Python
python实现数组插入新元素的方法
2015/05/22 Python
CentOS下Python3的安装及创建虚拟环境的方法
2018/11/28 Python
python3.7 sys模块的具体使用
2019/07/22 Python
Python3.7安装PyQt5 运行配置Pycharm的详细教程
2020/10/15 Python
桥梁与隧道工程专业本科生求职信
2013/10/08 职场文书
应届生程序员求职信
2013/11/05 职场文书
电大毕业自我鉴定
2014/02/03 职场文书
机关作风整顿个人剖析材料
2014/10/06 职场文书
2015年学生会干事工作总结
2015/04/09 职场文书
在js中修改html body的样式
2021/11/11 Javascript