·您当前的位置:首页 > 技术教程 > AS2与AS3技术 >

深入理解flash函数(AS2)(3)

时间:2011-06-24 14:56blogbus.com
六、引用函数 可以用函数的名字来引用一个函数。当将函数名与函数调用运算符(圆括号)结合起来使用时,函数就被调用了,但是名字本身只是作为对函数的引用。这就是说,实际上可以使用函数的名字来将一个引用赋予一个变

  六、引用函数

  可以用函数的名字来引用一个函数。当将函数名与函数调用运算符(圆括号)结合起来使用时,函数就被调用了,但是名字本身只是作为对函数的引用。这就是说,实际上可以使用函数的名字来将一个引用赋予一个变量。例如,一旦将对一个函数的引用赋予给一个变量,就可以将那个变量名与函数调用运算符结合起来调用那个函数。下面是一个例子:

  1. function 求面积(nA:Number,nB:Number):Number{   
  2. var nAnArea:Number=nA * nB;   
  3. return nArea;   
  4. }   
  5. var fArea:Function=求面积;   
  6. trece(fArea(6,6));//36 

下面将看到如何将匿名函数赋予变量。

  七、创建匿名函数

  现在已经知道如何使用标准的、命名的函数语法来定义函数了。除此之外,还有一种使用“匿名函数”来定义函数的方式,它允许创建一个没有名字的函数。然后,可以将该函数赋予一个变量。下面是匿名函数的语法:

function(参数):返回类型{
函数体
};

  读者可能注意到了,标准的函数声明和匿名函数声明在语法上很相似,仅有两点不同。第一,匿名函数没有函数名。第二,匿名函数后应该跟一个分号,这在标准函数的声明中是不需要的。正如前面所述,这主要是想将匿名函数赋予一个变量。否则,当该函数被定义之后,它就“离开了”作用域(即变成未定义的了)。下面是将匿名函数赋予一个变量的例子:

  1. var fSayHi:Function=function(sName:String):Void{   
  2. trace("Hi,"+sName);   
  3. );   
  4. fSayHi("Joey");//显示:Hi,Joey 

   就像所看到的那样,可以使用被赋予该匿名函数的变量来调用该匿名函数。实际上,匿名函数大家经常都在用,回想一下,按钮事件函数的写法,如:

  1. btn.onPress=funceton(){   
  2. ......   

  八、理解作用域

  “作用域”是在ActionScript中定义的某些标识符的作用范围。有些标识符仅在一个时间轴中被定义,有些标识符在整个影片的范围中被定义,有些标识符仅在一个函数中被定义。在函数中,有两种作用域需要解释一下:变量的作用域、函数的作用域。“变量的作用域”是变量在一个函数中的作用范围,“函数的作用域”是一个函数在一个影片中的作用范围。


  1、变量的作用域
  当在一个函数中适当地声明一个变量时,该变量就被称为“本地变量”。本地变量表示当在一个函数中声明一个变量时,它的定义在该函数调用之后就不再保留。这是一种避免与其他变量产生命名冲突的好方法。下面是一个函数的例子,它声明并初始化了一个名为sMessage的本地变量。该本地变量在该函数中被定义。但是,如果想使用trace()在该函数之外来显示该变量的值,结果将是未定义的。

  1. function testScope():Void{   
  2. var sMessage:String="hello,world!";   
  3. }   
  4. testScope();   
  5. trace(sMessage);//显示:undefined 

  在一个具有许多函数的大程序中,使用本地变量有利于确保减少具有相同名字的变量之间的冲突。尽管总是应该试图为变量取一个惟一的名字,但是在不同的函数中重复使用相同的变量名字还是可能的。如果每个都有相同的作用域,那么一个就会干扰另一个,就会导致不希望的值和结果。另一个使用本地变量的可能原因是用于内存管理。尽管它可能并不是真的很大,但在程序中定义的每个变量都会占用内存。如果不用一个变量做什么事了,但它仍被定义,就会浪费内存。通过使用本地变量,当函数结束之后内存就会被释放。参数被看做本地变量,即其作用域在该函数中,但不在它之外。从下面的例子就可以看出这一点:

  1. function testParameterScope(sMessage:String):Void{   
  2. trace(sMessage);   
  3. }   
  4. testParameterScope("Hello"); //显示:Hello   
  5. trace(sMessage);//显示:undefined 

  与此不同的是,在该函数外面声明的变量(但在定义该函数的相同时间轴中)是可以在该函数中使用的,例如:

  1. function testScopeTimeline():Void{   
  2. trace(sMessage);   
  3. }   
  4. Var sMessage:String="Hello";   
  5. testScopeTimeline();//显示:Hello 

  在该例子中,变量sMessage是在该函数之外声明的,但仍可以在该函数之中使用。

  九、函数的作用域

正如现在所知,当声明一个函数时,其作用域被限制在声明它的时间轴中。这就是说,可以通过它的名字在相同的时间轴中调用它;如果使用一个目标路径,那么就可以在那个时间轴之外调用它。在相同的时间轴中使用该函数,是非常容易的。在另一个时间轴中使用该函数,就有些不方便了。在一个没有时间轴的对象中使用该函数,就变得颇具挑战性了。试一试吧!

  十、创建递归

“递归”是指一个函数在其函数体中调用它自己。在某些情况下,这是一种必需的方法。递归的经典例子是计算一个数的阶乘。作为复习,数n的阶乘是指如下公式:
n*(n-1)*(n-2) … *1 例如,5的阶乘是120(即5*4*3*2*1)。下面就是一个完成这一工作的函数:

  1. function factorial(n:Number):Number{   
  2. if(n>O){   
  3. return n*factorial(n-1);   
  4. }   
  5. else{   
  6. return 1;   
  7. }   

递归是一个相当简单的概念,但对于还没有写过大量代码的人来说它又是一个头痛的概念。因此,有些时候它可能有些模糊。为了搞清该例子中的递归的工作原理,我们来看看当调用该函数时会发生什么。这次,我们使用一个小数字来使其简单些:trace(factorial(3));当第一次调用factorial()函数时,是用3这个值进行调用的。因为n大于0,所以它执行if语句中的语句。该语句指示函数返回表达式n*factorial(n-1)的值。为了计算该表达式,该函数必须调用它自己(factorial(n-1))。这一次,当调用factorial()时,是用2这个值进行调用的。同样,n的值大干0,所以执行第一个rettIrn语句。该函数再一次调用它自己。这一次,是用1这个值进行调用的。重复相同的处理,再一次用O这个值调用factorial()。然而,在这次函数调用时,因为n不再大于0了,所以返回1并且不再调用该函数了。应该非常小心,以确保递归函数在递归的次数上有一个限制。设想一下,如果这个例子的函数被写成下面这样,将会发生什么:

  1. function factorial(n:Number):Number{   
  2. return n*factorial(n-1);   

  该函数将永远地调用它自己。这个无限循环往往会导致系统崩溃。幸运的是,Flash对此有一个保护措施,即在一个设定的递归次数之后,会在影片中禁止ActionScript。如果在影片中使用了这种无限递归(即没有一个条件能使该递归停止)的函数,当测试影片时就会在Output窗口中看到警告信息。

 

热门文章推荐

请稍候...

保利威视云平台-轻松实现点播直播视频应用

酷播云数据统计分析跨平台播放器