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);
  ..
}

(0)

相关推荐

  • 有关于JS构造函数的重载和工厂方法

    写在前面 有时候我们希望对象的初始化有多种方式.比如通过元素组成的数组来初始化一个Set对象,而不是通过传入构造函数的参数列表来初始化它 重载overload 通过重载这个构造函数方法让它根据传入参数的不同,来执行不同的初始化方法. 复制代码 代码如下: function Set() {this.values = {}; // 用这个对象的属性保存这个集合this.n = 0; // 集合中值的个数 // 如果传入一个类数组的对象,将这个元素添加到集合中// 否则,将所有的参数都添加到集合中if

  • javascript中通过arguments参数伪装方法重载

    在很多面向对象的高级语言中,都有方法的重载.而javascript没有方法重载这个概念.但是我们可以通过arguments这个参数来伪装成函数的重载 在模拟之前我们先看一下代码: 复制代码 代码如下: //表面上没有声明形式参数的函数 function fun() { alert("示例代码"); } fun("小明", 100, true);//自己写了三个实际参数 通过结果我们看到,即使我们声明函数的时候没有定义形式参数,在调用方法的时候,我们也是可以写实际参数

  • JS模拟实现方法重载示例

    本文实例讲述了JS模拟实现方法重载.分享给大家供大家参考,具体如下: 在JS方法中,不能像C#方法能实现重载,但是我们可以通过js中的arguments来实现js方法的重载. 下面给出html实例: <html> <head> <title>JS方法的重载</title> <script> function testFun1(arm1){ /// <summary> /// JS重载测试被调用方法1 /// </summary&

  • 重载toString实现JS HashMap分析

    不过请仔细对比一下,你会发现其中差别还是很大的.Java HashMap的key是Object类型,所以可以任何类型的参数,而JS的key只能是字符串或是数字. 你也许会说,obj={};map[obj]=1;这段代码传入了既不是数字也不是字符的key,但也没发生错误啊.那是因为解释器将obj对象通过内置的toString方法转换成"[object Object]"这段字符了,你可以用for each下map看看.而java之所以能够接受任何类型的key,是因为其Object实现了Ha

  • js中方法重载如何实现?以及函数的参数问题

    都知道在js中没有办法直接实现方法重载,因为在js中如果定义了多个名称相同,但参数个数不一样的方法,其实只有最后一个方法能被真正调用,其他的方法都被覆盖掉了. 但每一个函数都有一个特殊的参数arguments,利用它可以实现方法的重载. 例如: 复制代码 代码如下: function Add(firstnumber,sencondnumber) { return firstnumber+sencondnumber; } 只能处理两个参数,如果有多个参数,或者没有参数,一个参数的情况都是处理不了的

  • 如何实现JS函数的重载

    javascript不能支持函数的重载,如下: 复制代码 代码如下: <script language="JavaScript"> function f(length) {     alert("高为:"+length); } function f(length,width) {     alert("高为:"+length+",宽为:"+width); } </srcipt> 上面那段代码其实是行不通

  • JS重载实现方法分析

    本文实例分析了JS重载实现方法.分享给大家供大家参考,具体如下: 重载是面向对象语言里很重要的一个特性,JS中没有真正的重载,是模拟出来的(因为js是基于对象的编程语言,不是纯面向对象的,它没有真正的多态:如继承.重载.重写) 一.什么时候用重载? 举例: function getDataTop10(){ alert("返回前10条数据"); } 后来需求改了,需要获得20条数据,而getDataTop10又被很多函数调用了,整体替换可以但麻烦,这时可以用重载 进而引出什么是重载:函数

  • js 覆盖和重载 函数

    学过JAVA的人对函数的覆盖和重载肯定是再熟悉不过了. 重载指两个或多个函数的参数类型,顺序和数量以及返回值不一样. 覆盖指两个或多个函数的参数类型,顺序和数量以及返回值完全一样. 那javascript真的有这种特性么? 回答是JS中函数重名只会采用最后一个定义. 首先来看下下面的代码 复制代码 代码如下: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEA

  • JavaScript 的方法重载效果

    在 JavaScript 的方法内,有个叫做 arguments 的变量数组,它是只读的,所有实际传入的参数变量都 放在了里面,通过它,我们可以对传入的参数进行类型检查,从而实现重载的效果. 判断一个变量的类型有两种方法. 1,用 typeof 语句: 复制代码 代码如下: function check(){ if(typeof arguments[0] == 'string') alert('你传入的参数是个字符串'); else if(typeof arguments[0] == 'numb

  • Javascript基础 函数“重载” 详细介绍

    Javascript不像其他编程语言一样具有函数签名(什么是函数签名,简单的说就是说函数的接受参数类型和参数个数,也有人认为返回类型也应该包括.具体概念大家可以到网上查询). 所以Javascript是不能像其他语言一样实现方法名相同,参数个数不同-的这类重载的,不信你可以试试: 复制代码 代码如下: function show(){             alert("1");         }         function show(num1){             a

  • JavaScript中的方法重载实例

    .NET里面的方法重载用着的确很方便,哪Javascript里面能不能也哪样做呢? Javasciprt里面本生是没有方法重载的功能,以前很多人的做法可能是直接少传参数过去,然后在根据参数是否为 "undefined" 未定义来决定怎么处理,从而实现类似方法重载的功能. 例如: 复制代码 代码如下: var showMessage = function(name,value,id){     if(id != "undefined"){         alert(

随机推荐