官术网_书友最值得收藏!

第4章 函數(shù)

函數(shù)在程序設(shè)計的過程中是一個“革命性”的創(chuàng)新。利用函數(shù)編程,可以避免冗長、雜亂的代碼;利用函數(shù)編程,可以重復(fù)利用代碼,提高程序效率;利用函數(shù)編程,可以便利地修改程序,提高編程效率。

函數(shù)(function)的準確定義為:執(zhí)行特定任務(wù),并可以在程序中重用的代碼塊。ActionScript 3.0中有兩類函數(shù):“方法”和“函數(shù)閉包”。具體是將函數(shù)稱為方法還是函數(shù)閉包,取決于定義函數(shù)的上下文。

4.1 定義函數(shù)

在ActionScript 3.0中有兩種定義函數(shù)的方法:一種是常用的函數(shù)語句定義法,一種是ActionScript中獨有的函數(shù)表達式定義法。具體使用哪一種方法來定義,要根據(jù)編程習(xí)慣來選擇。一般的編程人員使用函數(shù)語句定義法,對于有特殊需求的編程人員,則使用函數(shù)表達式定義法。

4.1.1 函數(shù)語句定義法

函數(shù)語句定義法是程序語言中基本類似的定義方法,使用function關(guān)鍵字來定義,其格式如下所示:

    function 函數(shù)名(參數(shù)1:參數(shù)類型,參數(shù)2:參數(shù)類型...):返回類型{
    //函數(shù)體
    }

代碼格式說明:

?function:定義函數(shù)使用的關(guān)鍵字,function關(guān)鍵字要以小寫字母開頭。

?函數(shù)名:定義函數(shù)的名稱。函數(shù)名要符合變量命名的規(guī)則,最好給函數(shù)取一個與其功能一致的名字。

?小括號:定義函數(shù)的必需格式,小括號內(nèi)的參數(shù)和參數(shù)類型均為可選。

?返回類型:定義函數(shù)的返回類型,也是可選的。要設(shè)置返回類型,冒號和返回類型必須成對出現(xiàn),而且返回類型必須是存在的類型。

?大括號:定義函數(shù)的必需格式,需要成對出現(xiàn)。括起來的是函數(shù)定義的程序內(nèi)容,是調(diào)用函數(shù)時執(zhí)行的代碼。

下面的代碼定義一個求和sum函數(shù),并調(diào)用函數(shù),輸出調(diào)用結(jié)果。代碼如下所示:

    function sum(a:int,b:int):int {
          //return為返回關(guān)鍵字
          return a + b;
    }
    trace(sum(1,2));//輸出:3

4.1.2 函數(shù)表達式定義法

函數(shù)表達式定義法有時也稱為函數(shù)字面值或匿名函數(shù)。這是一種較為繁雜的方法,在早期的ActionScript版本中廣為使用。其格式如下所示:

    var 函數(shù)名:Function=function(參數(shù)1:參數(shù)類型,參數(shù)2:參數(shù)類型...):返回類型{
    //函數(shù)體
    }

代碼格式說明:

?var:定義函數(shù)名的關(guān)鍵字,var關(guān)鍵字要以小寫字母開頭。

?函數(shù)名:定義的函數(shù)名稱。

?Function:指示定義數(shù)據(jù)類型是Function類。注意Function為數(shù)據(jù)類型,需大寫字母開頭。

?=:賦值運算符,把匿名函數(shù)賦值給定義的函數(shù)名。

?function:定義函數(shù)的關(guān)鍵字,指明定義的是函數(shù)。

?小括號:定義函數(shù)的必需格式,小括號內(nèi)的參數(shù)和參數(shù)類型均為可選。

?返回類型:定義函數(shù)的返回類型,可選參數(shù)。

?大括號:其中為函數(shù)要執(zhí)行的代碼。

需要注意的是,該方法首先定義的是一個匿名函數(shù),然后利用賦值運算符“=”把該函數(shù)賦值給定義的函數(shù)名。

下面是一個使用函數(shù)表達式定義法定義函數(shù)的示例,其代碼如下所示:

    var sum:Function=function(a:int,b:int):int {
          return a + b;
    }

4.1.3 兩種定義方法的區(qū)別和選擇

原則上推薦使用函數(shù)語句定義法,因為這種方法更加簡潔,更有助于保持嚴格模式和標準模式的一致性。

下面要講解的是函數(shù)語句和函數(shù)表達式定義法之間存在的區(qū)別,具體內(nèi)容如下所示。

1. 兩種方法的區(qū)別

函數(shù)語句和函數(shù)表達式定義法的作用域不同。函數(shù)語句作用于定義它的整個作用域(包括函數(shù)前面的語句)內(nèi),而函數(shù)表達式定義法的作用域只存在于其定義之后。簡單地說,函數(shù)語句定義法定義的函數(shù),無論在函數(shù)語句之前調(diào)用函數(shù)還是之后調(diào)用函數(shù),函數(shù)都可以被調(diào)用;而函數(shù)表達式定義法則必須先定義后調(diào)用,否則編譯就會報錯。

下面使用函數(shù)語句法定義一個函數(shù)hello(),并在定義之前調(diào)用,其代碼如下:

    hello();
    function hello() {
          var str:String="函數(shù)語句法定義前后都可以調(diào)用";
          trace(str);//輸出:函數(shù)語句法定義前后都可以調(diào)用
    }

下面使用函數(shù)語句法定義一個函數(shù)hello(),并在定義之后調(diào)用,其代碼如下:

    function hello() {
          var str:String="函數(shù)語句法定義前后都可以調(diào)用";
          trace(str);
    }
    hello();

下面使用函數(shù)表達式法定義一個函數(shù)hello(),并在定義之前調(diào)用,其代碼如下:

    hello();
    var hello:Function=function(){
    var str:String="函數(shù)表達式定義法不能提前調(diào)用";
    trace(str);
    };

注意 此段代碼不能正確編譯,輸出提示為“value不是函數(shù)”,說明此時函數(shù)hello()還沒有被定義。

下面使用函數(shù)表達式法定義一個函數(shù)hello(),并在定義之后調(diào)用,其代碼如下:

    var hello:Function=function(){
    var str:String="函數(shù)表達式定義法定義之后才能調(diào)用";
    trace(str);
    };
    hello();

函數(shù)語句和函數(shù)表達式定義法對this關(guān)鍵字的指向不同。函數(shù)語句定義法,this關(guān)鍵字永遠指向當前函數(shù)定義的域;而表達式定義法由于是匿名函數(shù)定義后被賦值為定義的函數(shù)變量,所以this的指向會隨著依附對象的不同而不同。

函數(shù)語句和表達式定義法在內(nèi)存管理和垃圾回收方面也存在不同。因為函數(shù)表達式不像對象那樣獨立存在,它是一個匿名函數(shù)。當引用這個函數(shù)的對象由于其他原因不再可用,那么將無法訪問該函數(shù)。

函數(shù)語句比包含函數(shù)表達式的賦值語句更便于閱讀。對比兩種定義方法,可以發(fā)現(xiàn),表達式定義法要求的語法內(nèi)容更多,代碼更加復(fù)雜,更容易造成編程時的混亂。

2. 兩種方法的選擇

在兩種定義方法的選擇上,一般使用函數(shù)語句定義法。函數(shù)表達式定義函數(shù)主要用于:一是適合關(guān)注運行時行為或動態(tài)行為的編程;二是用于那些使用一次后便丟棄的函數(shù)或者向原型屬性附加的函數(shù)。函數(shù)表達式更多地用在動態(tài)編程或標準模式編程中。

4.2 調(diào)用函數(shù)

函數(shù)只是一個編好的程序塊,在沒有被調(diào)用之前,什么也不會發(fā)生。只有通過調(diào)用函數(shù),函數(shù)的功能才能夠?qū)崿F(xiàn),才能體現(xiàn)出函數(shù)的高效率。通過本節(jié)的學(xué)習(xí),讀者將掌握一般的函數(shù)調(diào)用方法以及嵌套和遞歸調(diào)用函數(shù)的方法。

4.2.1 函數(shù)的一般調(diào)用

對于沒有參數(shù)的函數(shù),可以直接使用該函數(shù)的名字,并后跟一個圓括號(它被稱為“函數(shù)調(diào)用運算符”)來調(diào)用。

下面定義一個不帶參數(shù)的函數(shù)HelloAS(),并在定義之后直接調(diào)用,其代碼如下:

    function HelloAS() {
          trace("AS 3.0世界歡迎你!");
    }
    HelloAS();

代碼運行后的輸出結(jié)果如下所示。

    //輸出:AS 3.0世界歡迎你!

如果函數(shù)本身沒有參數(shù),就不能在調(diào)用的括號中輸入?yún)?shù),否則就會報錯。

下面定義一個不帶參數(shù)的函數(shù)HelloAS(),調(diào)用時輸入?yún)?shù)“我要走進AS 3.0世界”,其代碼如下:

    function HelloAS() {
          trace("歡迎走進AS 3.0世界");
    }
    HelloAS("我要走進AS 3.0世界");

注意 此段代碼不能正確編譯,輸出提示為“參數(shù)個數(shù)不正確,應(yīng)該為0個”,說明該函數(shù)無參數(shù),而調(diào)用輸入了參數(shù)。

對于含有參數(shù)的函數(shù),如果參數(shù)本身設(shè)有默認值,則函數(shù)名后的括號內(nèi)可以輸入?yún)?shù),也可以不輸入?yún)?shù)。

下面定義一個含有默認參數(shù)的函數(shù)HelloAS(),調(diào)用時不輸入?yún)?shù),其代碼如下:

    function HelloAS(str:String="AS 3.0世界歡迎你!") {
          trace(str);
    }
    HelloAS();

代碼運行后的輸出結(jié)果如下所示:

    //輸出:AS 3.0世界歡迎你!

但是,如果參數(shù)沒有設(shè)置默認值,那么函數(shù)名后的括號內(nèi)必須輸入?yún)?shù),而且輸入的參數(shù)類型必須和默認的參數(shù)類型一致,否則就會報錯。

下面定義一個含有默認參數(shù)的函數(shù)HelloAS(),調(diào)用時輸入?yún)?shù)“我要走進AS 3.0世界”,其代碼如下:

    function HelloAS(str:String="AS 3.0世界歡迎你!") {
          trace(str);
    }
    HelloAS("我要走進AS 3.0世界");

代碼運行后的輸出結(jié)果如下所示:

    //輸出:我要走進AS 3.0世界

下面定義一個含有參數(shù)的函數(shù)HelloAS(),調(diào)用時未輸入?yún)?shù),其代碼如下:

    function HelloAS(str:String) {
          trace(str);
    }
    HelloAS();

注意 此段代碼不能正確編譯,輸出提示為“參數(shù)個數(shù)不正確,應(yīng)該為1個”,說明該函數(shù)有一個參數(shù),而調(diào)用沒有輸入?yún)?shù)。

下面定義一個含有參數(shù)的函數(shù)HelloAS(),調(diào)用時輸入?yún)?shù)的數(shù)據(jù)類型和默認參數(shù)的數(shù)據(jù)類型不同,其代碼如下:

    function HelloAS(str:String) {
          trace(str);
    }
    HelloAS(1);

注意 此段代碼不能正確編譯,輸出提示為“int類型值的隱式強制指令的目標是非相關(guān)類型String”,說明輸入?yún)?shù)的數(shù)據(jù)類型是int,而不是默認的數(shù)據(jù)類型String。

當然,如果函數(shù)的參數(shù)沒有指定類型,則輸入的參數(shù)類型沒有強制要求。

另外,還可以通過函數(shù)的引用,把一個函數(shù)賦值給另一個變量。一旦將對一個函數(shù)的引用賦給一個變量,就可以將那個變量名與函數(shù)調(diào)用運算符結(jié)合起來調(diào)用那個函數(shù)。

下面的代碼把一個定義好的函數(shù)“求和”賦值給變量“sum”,并利用“sum”變量來調(diào)用函數(shù)“求和”:

    function 求和(a:int,b:int) {
          trace(a+b);
    }
    var sum:Function=求和;
    sum(1,2);

代碼運行后的輸出結(jié)果如下所示:

    3

4.2.2 嵌套和遞歸調(diào)用函數(shù)

嵌套和遞歸調(diào)用是兩種類似的函數(shù)調(diào)用方式,其本質(zhì)都是在調(diào)用函數(shù)時用一個函數(shù)調(diào)用另一個函數(shù)。不同的是,嵌套調(diào)用是用一個函數(shù)去調(diào)用另一個函數(shù),而遞歸調(diào)用是函數(shù)調(diào)用自身函數(shù)。

1. 嵌套調(diào)用函數(shù)

AS 3.0允許函數(shù)嵌套定義,即在一個函數(shù)體中再定義一個新函數(shù)。嵌套的層次可以是多層的,比如函數(shù)A可以調(diào)用函數(shù)B,而函數(shù)B又可以調(diào)用函數(shù)C??

下面先定義求整數(shù)和sum()函數(shù),它接受兩個參數(shù):一個字符型參數(shù)a和一個數(shù)字型參數(shù)b。為了求和,需要把參數(shù)a轉(zhuǎn)換為整數(shù)類型,把參數(shù)b轉(zhuǎn)換為整數(shù)類型。為此在函數(shù)體中定義STI()函數(shù)把字符型轉(zhuǎn)為整數(shù)型,定義NTR()函數(shù)把數(shù)字進行求整。程序代碼如下:

    function sum(a:String,b:Number) {
          function STI(c:String):int {
                return int(c);
          }
          function NTR(d:Number):int {
                return Math.round(d);
          }
          return STI(a) + NTR(b);
    }
    var a:String="10";
    var b:Number=5.56;
    trace(sum(a,b));

代碼運行后的輸出結(jié)果如下所示:

    16

注意 在嵌套函數(shù)內(nèi)部定義的函數(shù),僅在主函數(shù)體內(nèi)可用,除非將對嵌套函數(shù)的引用傳遞給外部代碼。

此外,嵌套函數(shù)也可以調(diào)用和自身函數(shù)并列的函數(shù),即允許在一個函數(shù)體內(nèi)調(diào)用另一個函數(shù)。同樣的功能,使用下面的代碼也可以實現(xiàn)。

    function sum(a:String,b:Number) {
          return STI(a) + NTR(b);
    }
    var a:String="10";
    var b:Number=5.56;
    trace(sum(a,b));
    function STI(c:String):int {
          return int(c);
    }
    function NTR(d:Number):int {
          return Math.round(d);
    }

代碼運行后的輸出結(jié)果如下所示:

    16

注意 使用此種方法嵌套調(diào)用函數(shù),外部的函數(shù)對整個作用域都是可用的。

2. 遞歸調(diào)用函數(shù)

程序調(diào)用自身的編程技巧稱為遞歸。遞歸調(diào)用是一個函數(shù)在其定義或說明中直接或間接調(diào)用自身的方法,它能夠把復(fù)雜的、大型的程序轉(zhuǎn)化成和原問題相似的小問題來處理。

下面的代碼使用遞歸函數(shù)的方法來求1+2+3+?+n的值,其代碼如下:

    function sum(n:int):int {
        if (n==1) {
                return 1;
        } else {
                return n + sum(n - 1);
        }
    }
    trace(sum(100));

代碼運行后的輸出結(jié)果如下所示:

    5050

注意 遞歸必須是有條件的,在定義的時候必須有一個明確的遞歸結(jié)束條件,稱為遞歸出口。缺少遞歸出口的代碼將永遠地調(diào)用自身,形成死循環(huán)。

如下面的遞歸求階乘(n!)的代碼是不正確的。

    function fac(n:int):int {
          return n * fac(n - 1);
    }
    trace(fac(100));

但是,F(xiàn)lash中對此有一個保護措施,在一定的遞歸次數(shù)之后,系統(tǒng)會終止ActionScript代碼的運行,并給出提示信息。

4.3 函數(shù)的返回值

主調(diào)函數(shù)通過函數(shù)的調(diào)用得到一個確定的值,此值被稱為函數(shù)的返回值。利用函數(shù)的返回值,可以通過函數(shù)進行數(shù)據(jù)的處理、分析和轉(zhuǎn)換,并能最終獲取想要獲得的結(jié)果。在本節(jié)我們主要學(xué)習(xí)函數(shù)返回值的獲取方法和獲取過程中的注意事項。

4.3.1 return語句

AS從函數(shù)中獲取返回值,使用return語句來實現(xiàn),語法格式如下:

    return 返回值

格式說明如下:

?return:函數(shù)返回值的關(guān)鍵字,必需的。

?返回值:函數(shù)中返回的數(shù)據(jù),既可以是字符串、數(shù)值等,也可以是對象,如數(shù)組、影片簡介等。

下面定義一個求圓形面積的函數(shù),并返回圓面積的值,其代碼如下:

    function 圓面積(r:Number):Number{
          var s:Number=Math.PI*r*r;
          return s;
    }
    trace(圓面積(5));

代碼運行后的輸出結(jié)果如下所示:

    78.53981633974483

上面的代碼中,return后的返回值是一個變量s,return后的返回值也可以是一個表達式。把上面的代碼修改如下,也可以實現(xiàn)相同的效果。

    function 圓面積(r:Number):Number{
          return Math.PI*r*r;
    }
    trace(圓面積(5));

代碼運行后的輸出結(jié)果如下所示:

    78.53981633974483

return語句在使用時還要注意下面幾點:

?同一個函數(shù)中可以有多個return語句,執(zhí)行到哪個return語句,哪一個return語句起作用。

下面的代碼在輸入不同的參數(shù)時,執(zhí)行的返回語句不同。

    function 選擇輸出(x:Number):Number {
          if (x>0) {
                return 1;
          } else if (x<0) {
                return -1;
          } else {
                return 0;
          }
    }
    trace(選擇輸出(10));

代碼運行后的輸出結(jié)果如下所示:

    1

說明

在輸入的參數(shù)大于0時,執(zhí)行return 1語句;參數(shù)小于0,執(zhí)行return-1語句;參數(shù)等于0,執(zhí)行return 0語句。

?return語句同時又是一個終止語句,只要執(zhí)行到return語句,F(xiàn)lash就終止執(zhí)行之后的代碼,跳出函數(shù)體。

從下面代碼的輸出結(jié)果,可發(fā)現(xiàn)return前的輸出語句可以執(zhí)行,而return后的輸出語句沒有被執(zhí)行。

    function 輸出測試() {
          trace("這是return前的語句,能夠被執(zhí)行");
          return;
          trace("這是return后的語句,不能被執(zhí)行");
    }
    輸出測試();

代碼運行后的輸出結(jié)果如下所示:

    這是return前的語句,能夠被執(zhí)行

?return語句后的返回值可以為空,此時返回為“undefined”。

下面的return語句沒有參數(shù),其代碼如下:

    function 輸出測試() {
          return;
          }
    trace(輸出測試());

代碼運行后的輸出結(jié)果如下所示:

    undefined

4.3.2 返回值類型

函數(shù)的返回類型在函數(shù)的定義中屬于可選參數(shù),如果沒有選擇,那么返回值的類型由return語句中返回值的數(shù)據(jù)類型來決定。

下面的代碼,return語句返回一個字符型數(shù)據(jù),來驗證一下返回值的類型。

    function 類型測試() {
          var a:String="這是一個字符串";
          return a;
    }
    trace(typeof(類型測試()));

代碼運行后的輸出結(jié)果如下所示:

    string

如果函數(shù)定義過程中設(shè)定了返回類型,則返回值的類型必須和設(shè)置的數(shù)據(jù)類型相同,否則編譯就會報錯。

把上面的函數(shù)增加一個返回類型Number,代碼如下:

    function 類型測試():Number {
          var a:String="這是一個字符串";
          return a;
    }
    trace(類型測試());

注意

此段代碼不能正確編譯,輸出提示為“String類型值的隱式強制指令的目標是非相關(guān)類型Number”,說明return返回的數(shù)據(jù)類型是String,而不是默認的返回類型Number。把返回類型Number改為String,代碼就能編譯通過。

若函數(shù)不需要返回數(shù)據(jù),也就是函數(shù)體中不存在return語句,那么定義函數(shù)時不能設(shè)置返回類型,否則編譯會報錯。下面的代碼不能夠被編譯:

    function 返回測試():String {
          var a:String="這是一個字符串";
          trace(a);
    }
    trace(返回測試());

注意 此段代碼不能正確編譯,輸出提示為“函數(shù)沒有返回值”,說明函數(shù)體中沒有返回語句。

4.4 函數(shù)的參數(shù)

函數(shù)通過參數(shù)向函數(shù)體傳遞數(shù)據(jù)和信息。ActionScript 3.0對函數(shù)的參數(shù)增加了一些新功能,同時也增加了一些限制。有大多數(shù)程序員都熟悉的按值或按引用傳遞參數(shù)這一概念,也有很多人相對陌生的arguments對象和...(rest)參數(shù)。

4.4.1 傳遞參數(shù)的語法

函數(shù)中傳遞的參數(shù)都位于函數(shù)格式的括號中,語法格式如下:

    (參數(shù)1:參數(shù)類型=默認值,參數(shù)2:參數(shù)類型=默認值)

下面定義一個個性化的歡迎語句,對不同的姓名給出對應(yīng)的問候。代碼如下所示:

    function Welcome(username:String):void {
          trace("歡迎你!"+username);
    }
    Welcome("張三");
    Welcome("小明");

代碼運行后的輸出結(jié)果如下所示:

    歡迎你!張三
    歡迎你!小明

ActionScript函數(shù)支持傳遞多個參數(shù)。在定義函數(shù)時,使用半角逗號分隔開不同的參數(shù)即可。下面定義一個多個參數(shù)的函數(shù),代碼如下所示:

    function intro(username:String,age:int):void {
          trace("你的姓名:"+username+"    年齡是:"+age);
    }
    intro("小王",25);

代碼運行后的輸出結(jié)果如下所示:

    你的姓名:小王    年齡是:25

注意 隔開參數(shù)的是半角逗號而不是分號。

在設(shè)置參數(shù)時不能使用var語法,否則編譯時就會報錯。下面的代碼使用var定義了參數(shù),不能編譯通過。

    function Hello(var username:String):void{
          trace("Hello."+username)
    }

4.4.2 傳遞參數(shù)的兩種方法

許多編程語言中,參數(shù)的傳遞基本都是兩種類型:按值或者按引用傳遞。按值傳遞意味著將參數(shù)的值復(fù)制到局部變量中以便在函數(shù)內(nèi)使用。按引用傳遞意味著將只傳遞對參數(shù)的引用,而不傳遞實際值。要了解任何一門編程語言中的函數(shù),首先必須搞清楚參數(shù)的傳遞到底是按值還是按引用。

在ActionScript 3.0中,所有的參數(shù)均按引用傳遞,因為所有的值都存儲為對象。基元型數(shù)據(jù)是不變的對象,按值還是按引用的效果一樣,通常可以看做是按值傳遞。按值傳遞,是指參數(shù)被傳遞給函數(shù)后,被傳遞的變量就獨立了。若在函數(shù)中改變這個變量,原變量不會發(fā)生任何變化。

下面來測試一下,代碼如下所示:

    function test(a:Number):Number {
          a++;
          return a;

    }
    var b:Number=5;
    trace("b引用前:"+b);
    var c=test(b);
    trace("b引用后:"+b);
    trace("c:"+c);

代碼運行后的輸出結(jié)果如下所示:

    b引用前:5
    b引用后:5
    c:6

說明

從輸出的結(jié)果可以看出,變量b在引用前和引用后,其值沒有變化,變化的是變量b的一個引用。

復(fù)雜類型數(shù)據(jù)不但按引用傳遞,而且還保持一個引用。這樣,在函數(shù)內(nèi)部參數(shù)的更改同樣會影響到函數(shù)外部數(shù)據(jù)。

下面先建立一個復(fù)雜型數(shù)據(jù)Array對象,然后在數(shù)組中給其追加一個數(shù)據(jù),結(jié)果發(fā)現(xiàn)數(shù)組的數(shù)據(jù)發(fā)生了改變。代碼如下所示:

    function TestArr(_arr:Array):void {
          var a:int=100;
          _arr.push(a);
    }
    var b:Array=[1,2,3];
    trace("引用前:"+b);
    TestArr(b);
    trace("引用后:"+b);

代碼運行后的輸出結(jié)果如下所示:

    引用前:1,2,3
    引用后:1,2,3,100

說明

從輸出的結(jié)果可以看出,數(shù)組變量b的值在引用前后發(fā)生了變化。

4.4.3 給函數(shù)設(shè)置默認參數(shù)

在ActionScript 2.0中并不支持對函數(shù)設(shè)置默認參數(shù),此為ActionScript 3.0的新功能。要給一個函數(shù)的參數(shù)設(shè)置默認值,語法格式如下:

    function(參數(shù)1:參數(shù)類型=默認值,參數(shù)2:參數(shù)類型=默認值)

默認參數(shù)是可選項,可以設(shè)置默認參數(shù),也可以不設(shè)置默認參數(shù)。若設(shè)置了默認參數(shù),則在調(diào)用函數(shù)時,如果沒有寫明參數(shù),系統(tǒng)將使用在函數(shù)定義中為該參數(shù)指定的值。

下面定義一個有3個參數(shù)的函數(shù),其中兩個參數(shù)有默認值。代碼如下所示:

    function Test(a:int,b:int=2,c:int=3):void {
          trace(a,b,c);
    }
    Test(1);            //輸出:1,2,3
    Test(1,4);          //輸出:1,4,3
    Test(1,4,0);        //輸出:1,4,0

參數(shù)設(shè)置了默認值,那么在調(diào)用時即為可選參數(shù),可以設(shè)置,也可以不設(shè)置,而沒有默認值的參數(shù)則必須輸入。

和上面相同的一個函數(shù),若在調(diào)用時不設(shè)置參數(shù),則編譯時會報錯。代碼如下所示:

    function Test(a:int,b:int=2,c:int=3):void {
          trace(a,b,c);
    }
    Test();

注意 此段代碼不能正確編譯,輸出提示為“參數(shù)個數(shù)不正確,應(yīng)該為1個”,說明默認參數(shù)在系統(tǒng)分析的時候并不計入必選參數(shù)之列。

4.4.4 arguments 對象和...(rest) 參數(shù)

ActionScript 3.0中有兩種函數(shù)調(diào)用時檢查參數(shù)數(shù)量的方法,分別為使用arguments對象和...(rest) 參數(shù)。

1. arguments對象

在函數(shù)中,可以使用arguments對象訪問有關(guān)傳遞給該函數(shù)的參數(shù)信息。arguments對象是一個數(shù)組,其中按順序保存著傳遞給函數(shù)的所有參數(shù)。可以使用數(shù)組的訪問方式來訪問傳入的參數(shù)。它有一個length屬性記錄當前傳入的參數(shù)數(shù)目,還有一個屬性callee提供對函數(shù)本身的引用,該引用可用于遞歸調(diào)用函數(shù)表達式。

在ActionScript 3.0中,函數(shù)調(diào)用中所包括的參數(shù)的數(shù)量可以大于在函數(shù)定義中所指定的參數(shù)數(shù)量,但是,如果參數(shù)的數(shù)量小于必需參數(shù)的數(shù)量,編譯時就會報錯。可以通過arguments對象的數(shù)組來訪問傳遞給函數(shù)的任何參數(shù),不管是否在函數(shù)定義中定義了該參數(shù)。下面使用arguments數(shù)組及arguments.length屬性來輸出傳遞給TestArg()函數(shù)的所有參數(shù)。代碼如下所示:

    function TestArg(a:int,b:int,c:int):void {
          trace("輸入的參數(shù)個數(shù)是:"+arguments.length);
          for (var i:uint = 0; i < arguments.length; i++) {
                trace("這是第"+i+"個參數(shù),其值為:"+arguments[i]);
        }
    }
    TestArg(1,2,3);

代碼運行后的輸出結(jié)果如下所示:

    輸入的參數(shù)個數(shù)是:3
    這是第0個參數(shù),其值為:1
    這是第1個參數(shù),其值為:2
    這是第2個參數(shù),其值為:3

注意 在ActionScript 3.0中,要遵守函數(shù)的嚴格定義。所以ActionScript 2.0中無視函數(shù)定義,傳入任意多個參數(shù)的做法在ActionScript 3.0中是非法的。

arguments.callee屬性通常用在匿名函數(shù)中以創(chuàng)建遞歸,以此來提高程序的靈活性。下面的函數(shù)表達式中,使用arguments.callee屬性來啟用遞歸。代碼如下所示:

    var fac:Function = function (i:uint){
          if(i == 1)      {
                return 1;
          }      else{
              return (i + arguments.callee(i - 1));
          }
    };
    trace(fac(100));// 輸出:5050

2. ...(rest)參數(shù)

...(rest)參數(shù)是ActionScript 3.0引入的新參數(shù)聲明。使用該參數(shù)可指定一個自己命名的數(shù)組參數(shù)來接受任意多個以逗號分隔的參數(shù)。其語法格式如下:

    function(..args)
    function(參數(shù)1,參數(shù)2,...args)

...(rest)參數(shù)擁有arguments對象的儲存功能和length屬性,但是不再具有callee屬性。

下面用...(rest)參數(shù)來重寫TestArg()函數(shù),代碼如下所示:

    function TestArg(...args):void {
          trace("輸入的參數(shù)個數(shù)是:"+args.length);
          for (var i:uint = 0; i < args.length; i++) {
                trace("這是第"+i+"個參數(shù),其值為:"+args[i]);
        }
    }
    TestArg(1,2,3);

代碼運行后的輸出結(jié)果如下所示:

    輸入的參數(shù)個數(shù)是:3
    這是第0個參數(shù),其值為:1
    這是第1個參數(shù),其值為:2
    這是第2個參數(shù),其值為:3

...(rest)參數(shù)還可與其他參數(shù)一起使用,但是要注意其只能是最后一個列出的參數(shù)。下面修改TestArg()函數(shù),增加一個int型參數(shù)x,第二個參數(shù)使用...(rest)參數(shù),輸出的結(jié)果將忽略第一個值。代碼如下所示:

    function TestArg(x:int,...args):void {
          trace("...(rest) 參數(shù)個數(shù)是:"+args.length);
          for (var i:uint = 0; i < args.length; i++) {
                trace("這是第"+i+"...(rest)參數(shù),其值為:"+args[i]);
        }
    }
    TestArg(1,2,3);

代碼運行后的輸出結(jié)果如下所示:

    ...(rest) 參數(shù)個數(shù)是:2
    這是第0...(rest)參數(shù),其值為:2
    這是第1...(rest)參數(shù),其值為:3

注意 此時...(rest) 參數(shù)中記錄的參數(shù)個數(shù)是總的參數(shù)個數(shù)減去定義過的參數(shù)。

arguments對象和...(rest)參數(shù)都可以作為一個數(shù)組儲存輸入的參數(shù),但是在使用...(rest)參數(shù)時, arguments對象不可用。

4.5 練習(xí)題

1. 簡述傳遞參數(shù)時,值類型和引用類型的區(qū)別,以及字符串String和數(shù)組Array屬于哪種類型。

2. 請嘗試完成:把數(shù)字1~100隨機不重復(fù)放到一個數(shù)組里。

3. “String類型值的隱式強制指令的目標是非相關(guān)類型Number”,可能產(chǎn)生這個編譯錯誤的原因是什么?

4. 關(guān)于函數(shù)的返回值,說法正確的是( )。

A. AS 3.0必須聲明函數(shù)的返回類型

B. 可以不聲明返回類型,也可以用“:void”定義函數(shù)無返回值,定義為void時,可以return null

C. 可以將函數(shù)返回類型設(shè)置為“*”號,代表函數(shù)可以返回任意類型的數(shù)據(jù)

D. 函數(shù)test():Object不能返回字符串數(shù)據(jù)

5. 在函數(shù)中,可以使用arguments對象來訪問有關(guān)傳遞給該函數(shù)的參數(shù)的信息,arguments有個屬性callee,它的用途是什么?

主站蜘蛛池模板: 色达县| 遂川县| 五河县| 射洪县| 启东市| 晴隆县| 彭水| 光山县| 札达县| 岚皋县| 晋州市| 根河市| 永嘉县| 重庆市| 城固县| 温泉县| 景宁| 晋宁县| 凌云县| 丹棱县| 余庆县| 富顺县| 西宁市| 江安县| 五华县| 九寨沟县| 香格里拉县| 常德市| 巴林右旗| SHOW| 红河县| 安阳市| 灵川县| 安达市| 元阳县| 托克托县| 喜德县| 吴桥县| 娄底市| 阳原县| 武平县|