[转]AS3 与 其他语言 的一些不同点
http://blog.csdn.net/Begin_Game/archive/2008/10/15/3081317.aspx
一:for each ... in與 for..in 一樣都是自動遍歷對象的屬性,不同的是for each...in 更像是為遍歷保存鍵值對的集合而產生的,而這些集合的類型可以是未聲明類型的對象,甚至XML文件,而在遍歷時循環中的循環變量類型聲明是用"*"號來表示,意為任意類型。1:遍歷未聲明類型對象:var arr:Object = {1:"jack",2:2046};for each(var i:* in arr){?trace(i);}/-----jack2046
2:遍歷XML:
var xml:XML = <beans>
????<bean>jack</bean>
????<bean>2046</bean>
???? </beans>;
for each(var item:* in xml.bean)
{
?trace(item);
}
/-----
jack
2046
二:break的特殊用法:
在AS3中,由于其作用于動畫的特殊性,孕生出很有意思的的label標簽用法。此label標簽不能獨立存在,必須依賴break、continue兩個跳轉關鍵字進行使用。
gotoout:for(var i:int = 0; i < 10; i++)
??{???
???for(var j:int = 0; j < 10; j++)
???{
????trace("i:" + i + ",j:" + j);
????if((i==0)&& (j==8)){
?????break gotoout;
????}
???}???
??}
/-----
i:0,j:0
i:0,j:1
i:0,j:2
i:0,j:3
i:0,j:4
i:0,j:5
i:0,j:6
i:0,j:7
i:0,j:8
在這里gotoout標簽包含了一個嵌套for循環,之中退出條件為 i=0 && j==8 時,則跳轉出整個循環;如換為continue則為:
gotoout:for(var i:int = 0; i < 10; i++)
??{???
???for(var j:int = 0; j < 10; j++)
???{????
????if((i==0)&& (j==8)){
?????trace("跳過第i:" + i + "? j:" + j +"次循環");
?????continue gotoout;
????}
????else
????{
?????trace("i:" + i + ",j:" + j);
????}
???}
???if((i==1))
???{
????break;
???}
??}
/---------
i:0,j:0
i:0,j:1
i:0,j:2
i:0,j:3
i:0,j:4
i:0,j:5
i:0,j:6
i:0,j:7
跳過第i:0? j:8次循環
i:1,j:0
i:1,j:1
i:1,j:2
i:1,j:3
i:1,j:4
i:1,j:5
i:1,j:6
i:1,j:7
i:1,j:8
i:1,j:9
當然也不一定是循環才能使用breank,但continue一定要配合循環使用
break:
trace("1");
gotoout:{
?trace("2");
?trace("3");
?break gotoout;
?trace("4");
?trace("5");
}
/-------
trace("1");
gotoout:{
?trace("2");
?trace("3");
?break gotoout;
?trace("4");
?trace("5");
}
continue:
trace("1");
gotoout:{
?trace("2");
?trace("3");
?continue gotoout;
?trace("4");
?trace("5");
}
/-------
1039: 找不到 continue 語句的目標。
標簽也可嵌套使用,但無論嵌套幾層,最終跳出哪層標簽由 break 標簽名 決定的
trace("1");
gotoout:{
?gotoout1:{
??gotoout2:{
???trace("2");
???trace("3");
???break gotoout2;
???trace("4");
???trace("5");
??}
??trace("gotoout1");
?}
?trace("gotoout");
}
/------
1
2
3
gotoout1
gotoout
如break gotoout2 換成 break gotoout ,則程序會直接跳出gotoout標簽,不會打印 gotoout1、gotoout。
三:局部變量可當全局變量使用
AS3的代碼編譯是提交給Flash Play優化后編譯,因此會出現在java和C++中不可想象的狀況。
for(var i:int =1; i<=3; i++)
{
?var str:String = "你好,正在循環";
?trace(i + ":循環內:" + str);
}
trace("循環外:" + str);
/-----
1:循環內:你好,正在循環
2:循環內:你好,正在循環
3:循環內:你好,正在循環
循環外:你好,正在循環
可以看到str是在for循環開始后在循環內部聲明并賦值的,但在循環結束后在循環外部依然正常使用了str這個變量,這是由于代碼在編譯過程中編譯器將聲明前置優化了。
var str:String;
.......
因此無論將var str:String 放在代碼塊的何處,編譯器總會將變量聲明優化前置。但為了程序的可維護性,最好還是按照java、C++等語言的嚴謹寫法書寫代碼。
局部變量雖可隨處聲明,但注意其賦值的有效性,如:
trace("循環外:" + str);
for(var i:int =1; i<=3; i++)
{
?var str:String = "你好,正在循環";
?trace(i + ":循環內:" + str);
}
/-----
循環外:null
1:循環內:你好,正在循環
2:循環內:你好,正在循環
3:循環內:你好,正在循環
程序在變量未賦值前就使用此變量,雖可編譯運行,但最終打印出str的值為null。
四:函數表達式
這一點很像js的匿名函數,可以說完全相同。
var func:Function = function(par:int){
?return par*8;
}
trace(func(8));
/-------
64
聲明了類型為Function名為func的變量,此變量的值很怪異,看上去完全是個函數,其實函數本身也是對象,把對象賦值給變量有什么不對呢?雖然java有匿名類、C#也引入了匿名函數,但它們因為的實現方式肯定沒有js與as3直觀和簡潔。匿名函數是由變量記錄這個無名函數的內存地址,而外部訪問是由變量作為介質的,因此刪除變量,等于刪除了這個無名函數。但值得注意的是,函數表達式本身的書寫方式導致不宜維護,因此如果沒有特別需要毋須將函數寫為匿名函數。
五:arguments
AS3函數使用中,可以給函數傳入一系列的參數,如:
function sub(par1:int,par2:int)
{
.....
}
在這之中,當參數傳入函數調用之后,AS3編譯器會生成一個名為arguments數組對象,它保存了當前函數傳入的參數的值,可以看作參入參數的備份。
function sub(par1:int,par2:int)
{
?par1 = 3;
?par2 = 4;
?var sub1:int = par1 + par2;
?var sub2:int = arguments[0] + arguments[1];
?trace("函數參數之和:" + sub1);
?trace("arguments之和:" + sub2);
}
sub(1,2);
/--------
函數參數之和:7
arguments之和:3
但這個備份數組僅限于參數是按值傳遞的情況下,如參數是以引用傳遞則arguments的值會跟著改變。
function sub(par:Array)
{
?par[0] = "jack";
?trace("函數參數:" + par);
?trace("arguments:" + arguments);
}
var arr:Array = new Array(1,2,3);
sub(arr);
/--------
函數參數:jack,2,3
arguments:jack,2,3
另外,arguments有個重要屬性:callee,就是call自己。如使用該屬性,程序會將arguments所在的當前函數按照callee的賦值再次執行一次
var bool:Boolean = true;
function sub(par:Array)
{
?par[0] = "jack";
?trace("函數參數:" + par);
?trace("arguments:" + arguments);
?if(bool)
?{
??bool = false;
??var arrbak:Array = new Array("開始執行callee",1,1);
??trace("開始執行callee");
??arguments.callee(arrbak);
?}
}
var arr:Array = new Array(1,2,3);
sub(arr);
/--------
函數參數:jack,2,3
arguments:jack,2,3
開始執行callee
函數參數:jack,1,1
arguments:jack,1,1
?
六、重載
一種OOP語言擁有重載特性是很習以為常的事,畢竟任何OOP語言都必須遵循OOP三大特質。有意思的是AS中,重載這樣在其他語言司空見慣的特性,在AS3出現以前都是不存在的(不僅AS,javascript、vbScript、ruby等常見腳本語言都不支持,到底是腳本啊 .... ),且AS3的重載說到底也是模擬重載,一種數組變通而已。
1:使用aruments的length屬性進行重載
function test(par1:int):void
{
?if(arguments.length == 1)
??trace("重載1");
?else if(arguments.length >1)
??trace("重載2");
?else
??trace("重載3");
}
test(1);
test(1,2);
test(1,2,3);
/--------------------
重載1
重載2
重載2
注意函數test在聲明時只聲明了 par1:int 一個參數,而在調用時程序連續調用了3次test,并且后兩次參數與函數聲明不符,多了。但編譯器如果運行在標準模式下編譯,是不會報錯也可以運行的,這樣arguments數組會擴大為你傳進來參數的個數,如test(1,2,3),arguments長度就是3了,程序中如果需要用到2、3,只能通過arguments[1]/[2]來找到多出的參數。用arguments時,注意編譯器一定要運行在標準模式下;參數只能比函數聲明多,不能少。
?
2:使用 ...(args) 來傳入不同參數。
注意:...(args) ,前面是3點,英文模式下的3點,不多不少。args是傳進來參數數組的名稱,可以任意。
function test(...args):void
{
?if(args.length == 1)
??trace("重載1");
?else if(args.length >1)
??trace("重載2");
?else
??trace("重載3");
}
test(1);
test(1,2);
test(1,2,3);
/--------------------
重載1
重載2
重載2
?
當使用...args ,在程序中就不能用arguments來獲取參數了,取而代之是args。...args 也可以與聲明參數一起使用
function test(par1:int,...args):void
{
?if(args.length == 1)
??trace("參數" + par1 + "? 重載1? args參數:" + args);
?else if(args.length == 2)
??trace("參數" + par1 + "? 重載2? args參數:" + args);
?else
??trace("參數" + par1 + "? 重載3? args參數:" + args);
}
test(1,1);
test(1,2,3);
test(1,2,3,4,5);
/---------------------
參數1? 重載1? args參數:1
參數1? 重載2? args參數:2,3
參數1? 重載3? args參數:2,3,4,5
這樣也變通模擬了函數重載,args是不需要編譯器標準的無論在嚴謹或標準模式都可運行;args使用后arguments不能使用包括其屬性;在給已聲明參數賦值后,接下來無論多少個參數編譯器都會將其作為數組傳給args。
轉載于:https://www.cnblogs.com/sun11086/archive/2009/12/05/1617385.html
總結
以上是生活随笔為你收集整理的[转]AS3 与 其他语言 的一些不同点的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一些数据库优化经验资料整理
- 下一篇: wpf数据显示控件