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 相关文章推荐
div当滚动到页面顶部的时候固定在顶部实例代码
May 27 Javascript
js 动态修改css文件的方法
Aug 05 Javascript
node.js超时timeout详解
Nov 26 Javascript
javascript随机显示背景图片的方法
Jun 18 Javascript
JavaScript实现向右伸出的多级网页菜单效果
Aug 25 Javascript
javascript省市级联功能实现方法实例详解
Oct 20 Javascript
jQuery实现选中弹出窗口选择框内容后赋值给文本框的方法
Nov 23 Javascript
在vue项目中使用Nprogress.js进度条的方法
Jan 31 Javascript
vue keep-alive请求数据的方法示例
May 16 Javascript
jQuery超简单遮罩层实现方法示例
Sep 06 jQuery
vue插件draggable实现拖拽移动图片顺序
Dec 01 Javascript
解决layui弹出层layer的area过大被遮挡的问题
Sep 21 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/21 PHP
探讨php define()函数及defined()函数使用详解
2013/06/09 PHP
关于更改Zend Studio/Eclipse代码风格主题的介绍
2013/06/23 PHP
[原创]smarty简单模板变量输出方法
2016/07/09 PHP
php实现登陆模块功能示例
2016/10/20 PHP
PHP读取并输出XML文件数据的简单实现方法
2017/12/22 PHP
传递参数的标准方法(jQuery.ajax)
2008/11/19 Javascript
Ext JS 4实现带week(星期)的日期选择控件(实战一)
2013/08/21 Javascript
JavaScript中判断两个字符串是否相等的方法
2015/07/07 Javascript
ionic实现滑动的三种方式
2016/08/27 Javascript
js通过指定下标或指定元素进行删除数组的实例
2017/01/12 Javascript
关于angular js_$watch监控属性和对象详解
2017/04/24 Javascript
jQuery事件_动力节点Java学院整理
2017/07/05 jQuery
关于jquery layui弹出层的使用方法
2018/04/21 jQuery
微信小程序通过保存图片分享到朋友圈功能
2018/05/24 Javascript
vue使用prop可以渲染但是打印台报错的解决方式
2019/11/13 Javascript
详解Node.js使用token进行认证的简单示例
2020/05/25 Javascript
Python中isnumeric()方法的使用简介
2015/05/19 Python
python编程开发之日期操作实例分析
2015/11/13 Python
解析Mac OS下部署Pyhton的Django框架项目的过程
2016/05/03 Python
Python实现通过文件路径获取文件hash值的方法
2017/04/29 Python
Python 基础教程之闭包的使用方法
2017/09/29 Python
Python编程django实现同一个ip十分钟内只能注册一次
2017/11/03 Python
python 读取文本文件的行数据,文件.splitlines()的方法
2018/07/12 Python
python实现图片识别汽车功能
2018/11/30 Python
python面向对象入门教程之从代码复用开始(一)
2018/12/11 Python
基于Python测试程序是否有错误
2020/05/16 Python
Python简单实现词云图代码及步骤解析
2020/06/04 Python
Python+OpenCV图像处理——图像二值化的实现
2020/10/24 Python
selenium+超级鹰实现模拟登录12306
2021/01/24 Python
毕业留言寄语大全
2014/04/10 职场文书
企业贷款委托书格式
2014/09/12 职场文书
2014年绩效考核工作总结
2014/12/11 职场文书
物业接待员岗位职责
2015/04/15 职场文书
centos7安装mysql5.7经验记录
2022/05/02 Servers
Python实现数据的序列化操作详解
2022/07/07 Python