javascript的重载

  有时候我们会在javascript中调用方法时, 只要方法名写对了, 即使参数列表不对也可以正常调用. 当然是不是跟你预想的一样工作时另外一回事儿. 本来倒是没注意这个现象, 因为我每次在js中调用方法时都是严格安装输入的参数列表来传数据的, 也没有吧两个js方法使用相同的命名, 但是刚好今天一个同事遇到了, 所以就来研究一下. 

  首先, js中的方法调用仅仅是看方法名, 对于参数列表对不对应一律不管. 也就是说你可以在页面中用GetAlert()来调用GetAlert(content)方法, 也可以使用GetAlert('a')来调用GetAlert()方法。如:

<input type="button" onclick="GetAlert()" value="argu0" />

function GetAlert(content)
{
alert("有参数,参数是" + content + "!");
}

  当然, 这样调用时获取不到参数的, 所以content会显示为undefined. 

  那么有人可能会问:如果我方法传了参数, 但是方法中没有接受的参数怎么办呢?

  针对这个问题, 我们可以在方法的内部用arguments来接收传入的参数. 实际上使用很简单, 接收第i个参数就是用arguments[i-1]来接收即可. 

 

  第二个问题, 如果js中同时有两个同名的方法, 那会调用谁呢, 是调用其中的一个, 还是根据参数列表来相应的调用呢. 请见下例: 

<input type="button" onclick="GetAlert()" value="argu0" />

function GetAlert()
{
alert("没有参数!");
}

function GetAlert(content)
{
alert("有参数,参数是" + content + "!");
}

  实际运行之后你就会发现, 它调用的不是和它相对应参数的那个方法, 而是后一个. 这个也很好理解: 因为js中不允许有重名的方法存在, 所以在解析到后一个方法时, 会将前一个方法覆盖掉. 所以无论你怎么调用, 只能调用后面的方法. 

  

  现在到了第三个问题了, 就是方法的重载. 

  我们都很熟悉了C#中的重载, 现在来复习下: C#中重载的特点是:两必须一可以:

  • 方法名必须相同
  • 参数列表必须不同
  • 返回值可以不同也可以相同 (实际上就是和返回值不相关)

  那么js中因为不能有两个方法名相同, 所以第一条肯定不能实现. 这也就说明了在js中没有办法实现像C#那样的重载了。但是我们看看在jquery中有些方法, 实现的似乎和重载一样, 如val()和val(''). 它是怎么实现的呢,答案就是刚才第一点中提到的arguments。

  通过下面的例子你就可以很明白的看出来是如何通过arguments来迂回的实现js的重载的:

function GetAlert()
{
    if (arguments.length == 0)
    {
        alert("没有参数!");
    }
    else if (arguments.length == 1)
    {
        var str = arguments[0].constructor;
        if (arguments[0].constructor == String)
        {
            alert("有一个String型参数,参数是" + arguments[0] + "!");
        }
        else if(arguments[0].constructor ==Date)
        {
            alert("有一个Date型参数,参数是" + arguments[0].toString() + "!");
        }
    }
    else
    {
        var argu = "";
        for (var i = 0; i < arguments.length; i++)
        {
            argu = argu + arguments[i] + ",";
        }
        alert("有大于一个的参数,参数是" + argu + "!");
    }
}

  看完了这个js方法相信大家都明白了, 原来是通过arguments.length和arguments[].constructor来实现区别参数的。这时调用起来就似乎实现了重载的功能:

<input type="button" onclick="GetAlert()" value="argu0" />
<input type="button" onclick="GetAlert('a')" value="argu1Str" />
<input type="button" onclick="GetAlert(new Date())" value="argu1Date" />
<input type="button" onclick="GetAlert('a','b')" value="argu2" />

  

  最后需要提醒一点, 虽然我们实现了重载功能, 但是你也看到了, 这样写的代码是很多且判断很多, 所以尽量少用这种代码来实现重载功能. 有时候我们需要问问自己:这个地方一定要用重载么?

 下面附上了本次的测试代码:

 

全部代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Title</title>
<script type="text/javascript" >


function GetAlert(content)
{
    alert("有参数,参数是" + content + "!");
}

function GetAlert()
{
    alert("没有参数!");
}

function GetAlert()
{
    if (arguments.length == 0)
    {
        alert("没有参数!");
    }
    else if (arguments.length == 1)
    {
        var str = arguments[0].constructor;
        if (arguments[0].constructor == String)
        {
            alert("有一个String型参数,参数是" + arguments[0] + "!");
        }
        else if(arguments[0].constructor ==Date)
        {
            alert("有一个Date型参数,参数是" + arguments[0].toString() + "!");
        }
    }
    else
    {
        var argu = "";
        for (var i = 0; i < arguments.length; i++)
        {
            argu = argu + arguments[i] + ",";
        }
        alert("有大于一个的参数,参数是" + argu + "!");
    }
}
</script>
</head>

<body>
<input type="button" onclick="GetAlert()" value="argu0" />
<input type="button" onclick="GetAlert('a')" value="argu1Str" />
<input type="button" onclick="GetAlert(new Date())" value="argu1Date" />
<input type="button" onclick="GetAlert('a','b')" value="argu2" />

</body>
</html>

  

posted @ 2012-12-29 22:35  zhangkai2237  阅读(859)  评论(0编辑  收藏  举报