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判断背景图片是否加载成功使用img的width实现
May 29 Javascript
iframe窗口高度自适应的实现方法
Jan 08 Javascript
iframe窗口高度自适应的又一个巧妙实现思路
Apr 04 Javascript
jQuery实现checkbox全选的方法
Jun 10 Javascript
jquery验证邮箱格式是否正确实例讲解
Nov 16 Javascript
AngularJs Understanding the Controller Component
Sep 02 Javascript
Javascript农历与公历相互转换的简单实例
Oct 09 Javascript
JavaScript无缝滚动效果的实例代码
Mar 27 Javascript
基于react组件之间的参数传递(详解)
Sep 05 Javascript
详谈commonjs模块与es6模块的区别
Oct 18 Javascript
前端js中的事件循环eventloop机制详解
May 15 Javascript
使用JS location实现搜索框历史记录功能
Dec 23 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
ajaxControlToolkit AutoCompleteExtender的用法
2008/10/30 Javascript
js对象之JS入门之Array对象操作小结
2011/01/09 Javascript
Struts2的s:radio标签使用及用jquery添加change事件
2013/04/08 Javascript
JavaScript设置首页和收藏页面的小例子
2013/11/11 Javascript
JS正则表达式获取分组内容的方法详解
2013/11/15 Javascript
js实现3D图片逐张轮播幻灯片特效代码分享
2015/09/09 Javascript
深入浅析AngularJS中的module(模块)
2016/01/04 Javascript
JavaScript判断变量是否为数组的方法(Array)
2016/02/24 Javascript
js 动态给元素添加、移除事件的实现方法
2016/07/19 Javascript
利用D3.js实现最简单的柱状图示例代码
2016/12/09 Javascript
从零开始学习Node.js系列教程之基于connect和express框架的多页面实现数学运算示例
2017/04/13 Javascript
vue .sync修饰符的使用详解
2018/06/15 Javascript
jQuery时间戳和日期相互转换操作示例
2018/12/07 jQuery
js 计算月/周的第一天和最后一天代码
2020/02/01 Javascript
Vue+Element-U实现分页显示效果
2020/11/15 Javascript
利用python程序帮大家清理windows垃圾
2017/01/15 Python
一个基于flask的web应用诞生(1)
2017/04/11 Python
Python抓取聚划算商品分析页面获取商品信息并以XML格式保存到本地
2018/02/23 Python
Python DataFrame 设置输出不显示index(索引)值的方法
2018/06/07 Python
使用sklearn之LabelEncoder将Label标准化的方法
2018/07/11 Python
在Python中输入一个以空格为间隔的数组方法
2018/11/13 Python
python3对拉勾数据进行可视化分析的方法详解
2019/04/03 Python
python实现猜拳小游戏
2020/04/05 Python
python计算波峰波谷值的方法(极值点)
2020/02/18 Python
基于python图像处理API的使用示例
2020/04/03 Python
css3实现wifi信号逐渐增强效果实例
2017/08/09 HTML / CSS
匡威荷兰官方网站:Converse荷兰
2018/10/24 全球购物
拉斯维加斯酒店、演出、旅游、俱乐部及更多:Vegas.com
2019/02/28 全球购物
英国领先的餐饮折扣俱乐部:Gourmet Society
2020/07/26 全球购物
毕业生求职的求职信
2013/12/05 职场文书
师德个人剖析材料
2014/02/02 职场文书
治庸问责心得体会
2014/09/12 职场文书
2014基建处领导班子“四风”对照检查材料思想汇报
2014/10/04 职场文书
三十年再续同学情倡议书
2019/11/27 职场文书
浅谈MySQL next-key lock 加锁范围
2021/06/07 MySQL
python对文档中元素删除,替换操作
2022/04/02 Python