JS函数重载的解决方案

 更新时间:2014年05月13日 15:29:36   作者:  
在面向对象的编程中,很多语言都支持函数重载,能根据函数传递的不同个数、类型的参数来做不同的操作,JS对它却不支持,需要我们额外做些小动作。

在面向对象的编程中,很多语言都支持函数重载,能根据函数传递的不同个数、类型的参数来做不同的操作,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);
  ..
}

相关文章

  • 原生js实现无缝轮播图效果

    原生js实现无缝轮播图效果

    本文主要分享了原生js实现无缝轮播图效果的示例代码,具有很好的参考价值,下面跟着小编一起来看下吧
    2017-01-01
  • js中base64、url和blob之间相互转换的3种方式(详细代码)

    js中base64、url和blob之间相互转换的3种方式(详细代码)

    这篇文章主要给大家介绍了关于js中base64、url和blob之间相互转换的3种方式,Blob和File是用来表示二进制数据的,而Base64则是一种编码方式,用来把二进制数据编码成可读的字符串,需要的朋友可以参考下
    2023-10-10
  • bootstrap table 数据表格行内修改的实现代码

    bootstrap table 数据表格行内修改的实现代码

    这篇文章主要介绍了bootstrap table 数据表格行内修改的实现代码,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-02-02
  • 微信小程序图片上传功能的实现方法

    微信小程序图片上传功能的实现方法

    在编写小程序的项目过程中,难免会有需要上传图片,下面这篇文章主要给大家介绍了关于微信小程序图片上传功能的实现方法,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-04-04
  • 详解webpack之scss和postcss-loader的配置

    详解webpack之scss和postcss-loader的配置

    本篇文章主要介绍了详解webpack之scss和postcss-loader的配置,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01
  • JS运算符简单用法示例

    JS运算符简单用法示例

    这篇文章主要介绍了JS运算符简单用法,结合实例形式详细分析了JavaScript各种逻辑运算符、数学运算符、关系运算符等相关操作技巧,需要的朋友可以参考下
    2020-01-01
  • IE8 兼容性问题(属性名区分大小写)

    IE8 兼容性问题(属性名区分大小写)

    属性名大小写问题,如属性window.screen.height
    2009-06-06
  • Web开发必知Javascript技巧大全

    Web开发必知Javascript技巧大全

     JavaScript是一个绝冠全球的编程语言,可用于Web开发、移动应用开发(PhoneGap、Appcelerator)、服务器端开发(Node.js和Wakanda)等等,通过本文给大家介绍Web开发必知Javascript技巧大全,需要的朋友参考下吧
    2016-02-02
  • JavaScript 字符串与数组转换函数[不用split与join]

    JavaScript 字符串与数组转换函数[不用split与join]

    下面的代码,不考虑他的运行效率的话,思路不错,大家可以看看,但在实际的应用中,我们仍然使用split或join来实现数组的操作。
    2009-12-12
  • 基于微前端qiankun的多页签缓存方案实践

    基于微前端qiankun的多页签缓存方案实践

    这篇文章主要介绍了基于微前端qiankun的多页签缓存方案实践,本文对qiankun框架的使用没有做太多的发散总结,官网和Github上已经有很多相关问题的总结和踩坑经验可供参考,需要的朋友可以参考下
    2022-08-08

最新评论