- ActionScript 3.0從入門到精通(視頻實戰(zhàn)版)
- 蔣國強 岳元亞等編著
- 2345字
- 2018-12-31 19:52:48
第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,它的用途是什么?
- DB2 V9權(quán)威指南
- Web前端開發(fā)技術(shù):HTML、CSS、JavaScript(第3版)
- HTML5移動Web開發(fā)技術(shù)
- Effective C#:改善C#代碼的50個有效方法(原書第3版)
- Java面向?qū)ο笏枷肱c程序設(shè)計
- 零基礎(chǔ)玩轉(zhuǎn)區(qū)塊鏈
- PHP+MySQL+Dreamweaver動態(tài)網(wǎng)站開發(fā)實例教程
- Mastering KnockoutJS
- Rust Essentials(Second Edition)
- Python機器學(xué)習(xí)之金融風(fēng)險管理
- C語言程序設(shè)計實訓(xùn)教程與水平考試指導(dǎo)
- Python從入門到精通(第3版)
- 區(qū)塊鏈架構(gòu)之美:從比特幣、以太坊、超級賬本看區(qū)塊鏈架構(gòu)設(shè)計
- C++ System Programming Cookbook
- Android開發(fā)進階實戰(zhàn):拓展與提升