深入理解flash函数(AS2)(2)
四、传递参数
某些函数不需要给它们传递任何信息。例如,前面一节中的dlsplayGreetlng()函数就不需要任何参数。换句话说,许多函数需要给它们传递参数。例如,如果dlsplayGreetlng()函数可以使用不同的姓名来显示个性化的问候,就会使dlsp]ayGreetlng()函数更加有趣了。有了参数,实现这一点就简单了。把上面的函数修改一下,如下所示:
function displayGreeting(姓名:String):Void{
trace("Hello."+姓名)
}
一旦用这种方式定义了该函数,就可以调用它了,并给它传递不同的参数值。某些例子如下所示:
displayGreeting("张三");//显示:Hello.张三
displayGreeting("李四");//显示:Hello.李四
在一个函数中,一个参数就是一个变量,当调用该函数时就给变量赋值。就像在displayGreeting()函数中所看到的那样,参数被命名为"姓名",在每次调用该函数的时候就给该参数设置值。当用值"张三"调用该函数时,该变量就被赋予了"张三";当用值"李四"调用该函数时,该变量就被赋予了"李四"。参数(变量)是在函数定义的圆括号中声明的。读者可能注意到了,参数的声明与常规变量的声明相似但略微不同。首先,声明的相似性在于,需要给变量创建一个名字并定义一个数据类型。但是,当声明一个参数时,不需要使用var关键字,也不需要使用分号,并且不能在圆括号中初始化一个参数。下面的代码是不正确地声明参数的例子,将产生错误:
- //不能使用var关键字。
- function displayGreeting(var 姓名:String):Void{
- trace("Hello."+姓名)
- }
- //不能使用分号。
- function displayGreeting(姓名:String;):Void{
- trace("Hello."+姓名)
- }
- //不要试着在圆括号中初始化变量。
- function displayGreeting(姓名:String="王麻子"):Void{
- trace("Hello."+姓名)
- }
如果想在函数中使用多个参数,该怎么办呢?很简单,当定义函数时,可以声明用逗号分隔开的多个参数。同样地,当调用该函数时,可以给它传递多个值,只需简单地用逗号分隔这些值即可。如下是具有多个参数的dlsp]ayGreetlng()函数的例子:
- function displayGreeting(姓名:String,体重:Number):Void{
- trace(姓名+"的体重是:"+体重);
- }
displayGreeting("张三",50);//显示:张三的体重是:50 ,读者可能注意到了,当开始将越来越多的参数添加到一个函数定义的参数列表中时,代码就开始超出编辑器的边界了。可以在Actions面板中启用自动换行功能。还可以在定义函数时将每个参数(或参数组)放置到新的一行中。这是一个通常采用的习惯,因为它能更容易地阅读一个由许多参数组成的函数的参数列表。语法是相同的,区别仅在于:参数列表中的每个参数都放在新的一行中,以便使它更容易阅读。例如:
- function displayGreeting(姓名:String,
- 体重:Number):Void{
- trace(姓名+"的体重是:"+体重);
- }
注意:定义函数的参数个数与调用时传递的参数个数不一定要相同,当然,如果该有的参数没有的话,可能函数不会正常工作,多个参数是按先后顺序依次“对号入座”的。
1、给参数传递值和引用。
当给函数传递参数时,参数是用两种方式之一进行传递的:按值和按引用。其区别与数据类型有关。
(1)基本数据类型,如string,number,Boolean,是按值传递的。这就是说,值被传递给了函数,而与该值所来自的变量的任何联系都被切断了。换句话说,当值被传递给函数后,任何被用于传递值的变量就独立了。下面是一个例子:
- function 引用测试(a:Number):Number{
- a++;
- return a;
- }
- var b:Number=5;
- var c:Number=引用测试(b);
- trace(b);
- trace(c);
- Output窗口会显示如下内容
- 5
- 6
在这个例子中,尽管b的值被传递给了函数,并且那个值在函数中被增加了1,但b仍保持它的值(5)。为什么?因为b的值被传递给了函数,而不是变量自己。然后,那个值在函数中被赋予了一个名为a的参数,被增加、被返回。然后,返回的值被赋予了一个新的名为c的变量。
(2)当引用数据类型被作为参数传递时,它们就按引用进行传递。这就是说,一个被传递给函数的对象是对该实际对象的一个引用。其结果是,在函数中对对象引用所做的任何事情都会影响到该对象本身。没有产生该对象的副本。下面是一个使用名为mBox的MovieClip实例的例子:
- function move(mA:MovieClip,X:Number,Y:Number):Void{
- mA._X=x;
- mA._y=y;
- }
- move(mBox,100,100);
上面这个例子将名为mBox的MovieClip对象移动到舞台的(100,100)处。
2、使用arguments属性。
现在所看见过的函数要么不使用任何参数,要么参数被声明为圆括号中的参数列表。但是,不管一个函数是否声明了任何参数,传递给函数的所有参数都被保存在一个名为arguments的特殊数组中。每个函数都有一个arguments变量(对象),当调用函数的时候,就在该函数中创建该变量。ActionScript并不强求函数定义中的参数个数与调用时传递给该函数的参数个数一致。其意思是在调用时没有被传递、但在函数的参数字符串中被定义过的任何值,都会具有一个undeflned值;而在函数调用中传递的任何值,如果在函数的参数定义中没有它,就会被忽略。因此,完全可以定义一个没有参数的函数,但仍然可使用arguments对象传递参数。下面是一个把arguments对象作为数组使用的例子:
- function traceParams():Void{
- for(i=0;i<arguments.length;i++)(
- trace(arguments[i]);
- }
- }
- traceParams("one","two","three");
在这个例子中,下面的内容会显示在Output窗口中:
one
two
three
在大多数函数中,声明参数要好得多。当重载一个函数或遇到相似情况时(参见“重载函数”一节),arguments对象很有用。每一个arguments对象都有两个特殊的引用函数的属性。尽管不常使用这些属性(caller和callee),但在某些情况下(特别是在开发高度抽象的函数时)这些属性却有用。如果有一个函数调用当前函数的话,arguments对象的caller属性就返回对这个函数的引用。如果没有另一个函数调用当前函数的话,caller属性就有一个null值。
- function function1():Void{
- function2();
- }
- function function2():Void{
- if(arguments.caller==function1)
- trace("function2 called from function1");
- else
- trace("function2 not called from function1");
- }
- function1();//Output:function2 called from function1
- function2();//Output:function2 not called from function1
一个函数的arguments对象的callee属性是对该函数本身的引用。可能不能立即看出为什么说这是有用的。但是,考虑一下匿名的递归函数的情况。可以像下面这样写一个可以递归地调用自己的函数:
- Var fFactorial:Function =function(nOperand:Number):Number{
- if(nOperand>0){
- return nOperand * arguments.callee(nOperand-1);
- }else{
- return 1;
- }
- }
五、从函数返回一个值
到现在为止,主要介绍了函数作为子程序的这一点。也就是说,函数可以将主程序分解为更小的、更易管理的片段。一方面,当函数用那种方式作为一个子程序时,函数并不需要返回一个值。另一方面,某些时候想创建一个函数,用它进行某些计算或操作,然后返回一个值。可以在一个函数中使用return语句来返回一个特定的值。return语句的语法如下所示:
return value;
当使用return语句从一个函数返回一个值时,应该指定要被返回的数据类型(在函数定义的圆括号后面指定)。在此之前的例子中,返回类型是Void(表示无返回)。但是,当返回一个字符串时,就应该将返回的数据类型设置成String;当返回一个数字时,就应该将返回的数据类型设置成Number,等等。下面是一个计算矩形面积的函数的例子,其返回值是数字:
- function 求面积(nA:Number,nB:Number):Number{
- var nAnArea:Number=nA * nB;
- return nArea;
- }
只要遇到return语句,Flash就退出该函数。因此,如果在return语句后面还有其他剩余代码,就不会再执行它们了。例如:
- function 求面积(nA:Number,nB:Number):Number{
- var nAnArea:Number=nA * nB;
- return nArea;
- trace("The area is:"+nArea);
- }
求面积(6,6);在上面的例子中,trace()语句总是不会被执行的。这是因为在函数中的return语句后面的代码是执行不到的。下面是一个使用几个return语句的例子。明显地,在任何对该函数的调用中,只可能遇到其中的一个return语句。而在这个例子中,一个return语句是在条件满足时遇到的,其他return语句是在条件不满足时遇到的。该函数接受两个参数:一个(字符串)数组、一个字符串值。该函数用一个for语句来搜索遍历该数组,直到遇到一个与该字符串匹配的成员为止。一旦发现匹配,它就返回相应的索引。如果没有发现匹配,该函数就返回null。
- function findMatchingIndex(aTitles:Array,sTitle:String):Number{
- //循环遍历数组中的所有成员。
- for(var i:Number=0;i<aTitles.length;i++){
- //如果成员之一匹配sTitle的值,就返回相应的索引。这会导致该函数停止执行。
- if(aTitles[i]==sTitle){
- return i;
- }
- }
- //如果没有发现匹配,就会遇到这条语句(仅此而已)。
- return null;
- }
不管函数做什么,只要它返回一个值,就完全可以将其作为表达式的一部分来调用该函数。例如,可以用下面的方法来使用“求面积”函数:
var nArea:Number=求面积(6,6);//返值存入变量
也可以:
var nArea:Number=求面积(6,3) * 5;//函数参与计算
从本质上说,该函数就变成了一个类似字符串、数字、变量的值。因此,尽管下面的内容是有效的,然而却是不太有用的ActionScript语句:
6;
下面也一样:
求面积(6,6);
我们希望按某些有意义的方法来使用返回的值。可以像使用变量那样来使用一个会返回值的函数。我们已经见过用于赋值语句中的“求面积”函数了。下面是另外一个例子,在该例子中,函数作为条件表达式的一部分使用:
- if(求面积(6,6)>18){
- trace("The area is more than 18.");
- }
注意:函数的返回“值”不但可以是数值,字串等,也可以是对象,如数组、Object等。
热门文章推荐
- [HLS]做自己的m3u8点播系统使用HTTP Live Streaming(HLS技术)
- [FMS]FMS流媒体服务器配置与使用相关的介绍
- [AS3]什么是M3U8,与HTML5的区别是什么
- AS2.0 让flash自适应全屏,并且不自动缩放
- [AS3]as3.0的sound类常用技巧整理
- [AS3]as3与ByteArray详解、ByteArray介绍、ByteArray用法
- 关于RTMP,RTMPT,RTMPS,RTMPE,RTMPTE协议的介绍
- [JS]分享浏览器弹出窗口不被拦截JS示例