日期:2007.7.29
上次我们在《 在JavaScript中使用面向对象》讨论了对象的声明、成员的声明、全局变量和局部变量以及命名空间的处理。本文继续讨论面向对象,今天介绍 方法重载。
同时上次有人询问Function对象的 apply方法和 call方法的区别,本文将一并进行探讨。
首先我们需要知道Javascript有很多语言特点使得我们不能完全按照以往的编程经验进行编程,比如方法重载。在前一篇文章中,我们已经介绍过,在Javascript中后面的同名变量会覆盖前面的,所以想直接声明重载方法是不可行的。但是,Javascript的魅力就在于灵活,因此所有的期望都必然得到答案。
为了节省时间,今天我将所有的代码集中在一起,不再独立讲解,请看如下代码:
<
script type
=
'text
/
javascript'
>
function ABC()
{
this .member = 1 ;
this .method = Show;
}
function Show(a,b,c)
{
this .member = 123 ;
if (arguments.length == 1 )
if (arguments[ 0 ].constructor == Number)
Show1_int.apply( this , arguments);
else if (arguments[ 0 ].constructor == Date)
Show1_date.apply( this , arguments);
else
Show1_string.apply( this , arguments);
if (arguments.length == 2 )
if (arguments[ 0 ].constructor == Array)
Show3.apply( this ,arguments);
else
Show2.apply( this ,arguments);
}
function Show1_int(a)
{
alert(' 1 integer input parameter ' + a + ' methode is called');
}
function Show1_string(a)
{
alert(' 1 string input parameter ' + a + ' methode is called');
}
function Show1_date(a)
{
alert(' 1 date input parameter ' + a + ' methode is called');
}
function Show2(a,b)
{
alert(' 2 input parameter is transfer:\na:' + a + '\nb:' + b + '\nthe member is' + this .member);
}
// 演示引用方式传递
function Show3(a,b)
{
arguments[ 0 ][ 0 ] = 2 ;
alert(' 2 input parameter is transfer:\na:' + a + '\nb:' + b + '\nthe member is' + this .member);
}
var o = new ABC();
var arr = new Array();
arr[ 0 ] = 321 ;
o.method(arr[ 0 ], 2 ); // 值传递
alert(arr[ 0 ]); // 原始值未改变
o.method(arr, 2 ); // 引用方式传递
alert(arr[ 0 ]); // 方法调用时被方法修改
o.method( new Date());
script >
function ABC()
{
this .member = 1 ;
this .method = Show;
}
function Show(a,b,c)
{
this .member = 123 ;
if (arguments.length == 1 )
if (arguments[ 0 ].constructor == Number)
Show1_int.apply( this , arguments);
else if (arguments[ 0 ].constructor == Date)
Show1_date.apply( this , arguments);
else
Show1_string.apply( this , arguments);
if (arguments.length == 2 )
if (arguments[ 0 ].constructor == Array)
Show3.apply( this ,arguments);
else
Show2.apply( this ,arguments);
}
function Show1_int(a)
{
alert(' 1 integer input parameter ' + a + ' methode is called');
}
function Show1_string(a)
{
alert(' 1 string input parameter ' + a + ' methode is called');
}
function Show1_date(a)
{
alert(' 1 date input parameter ' + a + ' methode is called');
}
function Show2(a,b)
{
alert(' 2 input parameter is transfer:\na:' + a + '\nb:' + b + '\nthe member is' + this .member);
}
// 演示引用方式传递
function Show3(a,b)
{
arguments[ 0 ][ 0 ] = 2 ;
alert(' 2 input parameter is transfer:\na:' + a + '\nb:' + b + '\nthe member is' + this .member);
}
var o = new ABC();
var arr = new Array();
arr[ 0 ] = 321 ;
o.method(arr[ 0 ], 2 ); // 值传递
alert(arr[ 0 ]); // 原始值未改变
o.method(arr, 2 ); // 引用方式传递
alert(arr[ 0 ]); // 方法调用时被方法修改
o.method( new Date());
script >
我们无法直接定义重载方法,但是却可以为其他函数定义一个公开的重载方法调用。通过这种方式,对于调用者而言,重载的方法是透明的,只需调用方法名并传入适当的参数即可,与多数高级语言一样,不可定义传入参数相同而返回类型不同的重载方法。
下面我们再分析一下call和apply的区别,所有的函数都具有这两个方法,它们在使用上没有太大差别,主要区别就在于传入参数不同:
call使用可变参数序列进行值传递,而apply则使用数组或者arguments对象进行传递。
call方法的语法:
call([thisObj[,arg1[, arg2[, [,.argN]]]]])
参数
thisObj
可选项。将被用作当前对象的对象。
arg1, arg2, , argN
可选项。将被传递方法参数序列。
说明
call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。
call([thisObj[,arg1[, arg2[, [,.argN]]]]])
参数
thisObj
可选项。将被用作当前对象的对象。
arg1, arg2, , argN
可选项。将被传递方法参数序列。
说明
call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。
apply方法的语法:
apply([thisObj[,argArray]])
参数
thisObj
可选项。将被用作当前对象的对象。
argArray
可选项。将被传递给该函数的参数数组。
说明
如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。
如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。
apply([thisObj[,argArray]])
参数
thisObj
可选项。将被用作当前对象的对象。
argArray
可选项。将被传递给该函数的参数数组。
说明
如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。
如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。
注:以上资料来自《Jscript参考手册》
小节:通过show2方法,我们看到使用call或者apply方式可以将当前对象传递到方法内部,以此来访问当前对象的一些成员。这使得我们可以定义一些方法,给不同的自定义类进行调用,具体可以查看上篇文章我们定义的一个继承结构。
同时通过上面例子我们还演示了两者进行传递时,参数的传递方式会根据参数的不同而不同,如果是值变量则使用值传递,否则以引用方式传递。
尾声:当我们使用JavaScript的时候,你必须了解和掌握JavaScript的一些特点,它跟高级编程语言存在着一些区别,它灵活的特点给我们的开发带来了极大的灵活性,因此一旦深入JavaScript编程,我保证,你会毫无理由的喜欢上它。