所谓 函数重载(method overloading) ,就是函数名称一样,但是输入输出不一样。或者说,允许某个函数有各种不同输入,根据不同的输入,返回不同的结果。凭直觉, 函数重载 可以通过 if…else 或者 switch 实现,这就不去管它了。jQuery之父John Resig提出了一个非常巧(bian)妙(tai)的方法,利用了闭包。
从效果上来说, people 对象的 find 方法允许3种不同的输入: 0个参数时,返回所有人名;1个参数时,根据firstName查找人名并返回;2个参数时,根据完整的名称查找人名并返回。
难点在于, people.find 只能绑定一个函数,那它为何可以处理3种不同的输入呢?它不可能同时绑定3个函数 find0 , find1 与 find2 啊!这里的关键在于 old 属性。
由addMethod函数的调用顺序可知,people.find最终绑定的是find2函数。然而,在绑定find2时,old为find1;同理,绑定find1时,old为find0。3个函数find0,find1与find2就这样通过闭包链接起来了。
根据 addMethod 的逻辑,当 f.length 与 arguments.length 不匹配时,就会去调用 old ,直到匹配为止。
javascript不能支持函数的重载,如下:复制代码
代码如下:
<script language="JavaScript">
function f(length)
{
alert("高为:"+length)
}
function f(length,width)
{
alert("高为:"+length+",宽为:"+width)
}
</srcipt>
上面那段代码其实是行不通的,因为函数定义时的参数个数和函数调用时的参数个数没有任何关系。 在函数中可以用f.arguments[0]和f.arguments[1]得到调用时传入的第一和第二个参数,所以定义function(length),后面用f(10,10)调用是没有问题的。所以在上面这段代码中,第二个函数是永远不可能被调用到的,那么,要怎样才能实现像函数重载那样的功能呢?
那就是在函数定义中用f.arguments.length判断一下调用时传入的参数个数。然后对不同的情况采用不同的处理方式。
如下:
复制代码
代码如下:
<script language="JavaScript">
function f()
{
var len= arguments.length
if(1 == len)
{
var length = arguments[0]
var width = arguments[1]
f2(length,width)
}
else
{
var length = arguments[0]
f1(length)
}
}
function f1(length)
{
alert("高为:"+length)
}
function f2(length,width)
{
alert("高为:"+length+",宽为:"+width)
}
</srcipt>
这样,你就可以给函数f()传入一个参数也可以传入两个参数了,比如f(10)和f(10,10);
个人觉得,这样虽然可以实现重载,但也不是很好用,我们可以根据具体情况在一个函数中实现重载,如果要重载的两个函数相差较大,那就保留两个函数,而如果两个函数的实现基本差不多,那么可以在一个函数中进行判断,处理不同的部分,而不需要像上面那样写成三个函数,如下:
复制代码
代码如下:
<script language="JavaScript">
function f(length)
{
var len= arguments.length
if(1 == len)
{
var width = arguments[1]
alert("高为:"+length+",宽为:"+width)
}
else
{
alert("高为:"+length)
}
}
</srcipt>