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 相关文章推荐
js中document.write的那点事
Dec 12 Javascript
比例尺、缩略图、平移缩放之百度地图添加控件方法
Aug 03 Javascript
JS解决iframe之间通信和自适应高度的问题
Aug 24 Javascript
JS实现点击网页判断是否安装app并打开否则跳转app store
Nov 18 Javascript
JS实现HTML标签转义及反转义
Apr 14 Javascript
vue双向绑定简要分析
Mar 23 Javascript
js编写简单的聊天室功能
Aug 17 Javascript
jQuery实现的form转json经典示例
Oct 10 jQuery
webpack vue项目开发环境局域网访问方法
Mar 20 Javascript
JS实现的3des+base64加密解密算法完整示例
May 18 Javascript
vue项目中监听手机物理返回键的实现
Jan 18 Javascript
原生JS中应该禁止出现的写法
May 05 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 文件缓存函数
2011/10/08 PHP
PHP设计模式(八)装饰器模式Decorator实例详解【结构型】
2020/05/02 PHP
jquery下异步提交表单 异步跨域提交表单
2010/11/17 Javascript
基于JQuery实现的类似购物商城的购物车
2011/12/06 Javascript
javascript获取网页中指定节点的父节点、子节点的方法小结
2013/04/24 Javascript
在Ubuntu系统上安装Node.JS的教程
2015/10/15 Javascript
Bootstrap每天必学之导航条(二)
2016/03/01 Javascript
jQuery获取同级元素的简单代码
2016/07/09 Javascript
微信小程序 wx.login解密出现乱码的问题解决办法
2017/03/10 Javascript
Vue的移动端多图上传插件vue-easy-uploader的示例代码
2017/11/27 Javascript
微信小程序 Storage更新详解
2019/07/16 Javascript
vue 查看dist文件里的结构(多种方式)
2020/01/17 Javascript
vue商城中商品“筛选器”功能的实现代码
2020/07/01 Javascript
在vue项目中 实现定义全局变量 全局函数操作
2020/10/26 Javascript
vue 数据双向绑定的实现方法
2021/03/04 Vue.js
[59:30]完美世界DOTA2联赛PWL S3 access vs LBZS 第二场 12.20
2020/12/23 DOTA
python-opencv在有噪音的情况下提取图像的轮廓实例
2017/08/30 Python
Python实现的插入排序算法原理与用法实例分析
2017/11/22 Python
Python进程间通信Queue实例解析
2018/01/25 Python
python获取文件路径、文件名、后缀名的实例
2018/04/23 Python
Python实现的多进程拷贝文件并显示百分比功能示例
2019/04/09 Python
Python3.5 + sklearn利用SVM自动识别字母验证码方法示例
2019/05/10 Python
pytorch 实现打印模型的参数值
2019/12/30 Python
Python tkinter和exe打包的方法
2020/02/05 Python
Pandas实现一列数据分隔为两列
2020/05/18 Python
Python实现JS解密并爬取某音漫客网站
2020/10/23 Python
泰国综合购物网站:Lazada泰国
2018/04/09 全球购物
Antler英国官网:购买安特丽行李箱、拉杆箱
2019/08/25 全球购物
电大毕业生自我鉴定
2013/11/10 职场文书
致短跑运动员广播稿
2014/01/09 职场文书
售房委托书
2014/08/30 职场文书
2014年司法局工作总结
2014/12/11 职场文书
辣妈辣妹观后感
2015/06/10 职场文书
运动员入场前导词
2015/07/20 职场文书
《迟到》教学反思
2016/02/24 职场文书
JavaScript 原型与原型链详情
2021/11/02 Javascript