2011年7月19日 星期二

[AS3] 命名空間namespace及小實例

※ 應將public、private、protected、internal存取控制指定字視為內建的命名空間。
※ 命名空間可控制方法和屬性的能見度。
※ 屬性和方法的名稱永遠包含識別名稱和命名空間。只要定義之前未有命名空間特質,預設就會以internal命名空間加以限定。(只有在相同套件內的呼叫者才看得見)

※ 使用命名空間三個基本步驟:

(A) 定義命名空間:使用 namespace 關鍵字來定義命名空間
//使用public讓其它套件的程式碼獲取namespaceExample命名空間的可見度
package  example{
public namespace namespaceExample;
}


(B) 套用命名空間:
namespaceExample function doJob():void{}


(C) 參考命名空間:
  1. 用 use namespace 指令參考命名空間
    use namespace namespaceExample;

    var counterAddition:CounterAddition = new CounterAddition();

    counterAddition.doJob(1,2);

    trace(counterAddition.getAnswer);

  2. 或 使用名稱修飾語 (::) 標點符號
    var counterAddition:CounterAddition = new CounterAddition();

    counterAddition.namespaceExample::doJob(1,2);

    trace(counterAddition.namespaceExample::getAnswer);


※ 命名空間namespace小小實例
當public、private、protected、internal四個存取控制指定子的存取權限不符合使用,比如說有一些「方法」分散在不同套件的類別裡,若想讓所有套件都可以存取,但又不想讓這些方法變成公用方法,此時就可透過建立命名空間namespace,做為自定義的特殊存取控制指定子。以下例子將不同套件內的類別方法,整合到相同的命名空間中,透過參照命名空間的use namespace陳述式,或名稱修飾語 (::) 標點符號可調用這些方法。


下圖為檔案結構:



1000718_namespaceT1.fla





//namespaceExample.as
package  example{
public namespace namespaceExample;
}


//CounterAddition.as
package  example.addition{
import example.namespaceExample;
public class CounterAddition  {
public var answer:Number;
public function CounterAddition() {
return;
}
namespaceExample function doJob(_a:Number,_b:Number):void{
this.answer = _a + _b;
return;
}
namespaceExample function get getAnswer():Number{
return this.answer;
}
}
}


CounterSubtraction.as
package example.subtraction {
import example.namespaceExample;
public class CounterSubtraction {
public var answer:Number;
public function CounterSubtraction() {
return;
}
namespaceExample function doJob(_a:Number,_b:Number):void{
this.answer = _a - _b;
return;
}
namespaceExample function get getAnswer():Number{
return this.answer;
}
}
}


NamespaceT1_1000718.as
package  {
import flash.display.MovieClip;
import example.namespaceExample;
import example.addition.CounterAddition;
import example.subtraction.CounterSubtraction;

public class NamespaceT1_1000718 extends MovieClip {
public function NamespaceT1_1000718() {
var counterAddition:CounterAddition = new CounterAddition();
counterAddition.namespaceExample::doJob(1,2);
trace(counterAddition.namespaceExample::getAnswer);
var counterSubtraction:CounterSubtraction = new CounterSubtraction();
counterSubtraction.namespaceExample::doJob(3,1);
trace(counterSubtraction.namespaceExample::getAnswer);
/*use namespace namespaceExample;
var counterAddition:CounterAddition = new CounterAddition();
counterAddition.doJob(1,2);
trace(counterAddition.getAnswer);
var counterSubtraction:CounterSubtraction = new CounterSubtraction();
counterSubtraction.doJob(3,1);
trace(counterSubtraction.getAnswer);*/
return;
}
}
}







Download

[AS3] 變數範圍之「升舉」技術

AS3變數有一個叫做「升舉」的技術,允許在變數宣告之前,讀取或寫入變數。
透過此項技術,編譯器會將變數宣告移至函數的最上層。


但編譯器並不會升舉任何指定陳述式
即只升舉宣告變數的部份,但不會升舉指定值給變數的部份。

(例一)

trace(num); //trace得NaN,NaN是Number型別的預設值,代表num已經宣告,但尚未初始化(賦值)
var num:Number = 100;
trace(num); //100
trace("**********************");

trace(str); //null
var str:String = "Hello";
trace(str); //Hello
trace("**********************");

aUint = 66;
trace(aUint); //66,先賦值,底下才宣告,透過「升舉」,var aUint:uint的宣告被移到最上方
var aUint:uint = 99;
trace(aUint); //99















(例二)

trace(mc); //null ←Object型別的預設值(代表mc此時已升舉宣告)
myFunc();

function myFunc():void{
trace("myFunc !!!"); //myFunc !!!
mc = new MyObject();
trace(mc); //[object MyObject]
}

var mc:Object;
trace(mc); //[object MyObject]



將(例二)修改如以下:

trace(mc); //null ←Object型別的預設值(代表mc此時已升舉宣告)(但指定賦值部份並未被升舉)
myFunc();

function myFunc():void{
trace("myFunc !!!"); //myFunc !!!
trace(mc); //null
}

var mc:Object = new MyObject();
trace(mc); //[object MyObject]







2011年7月18日 星期一

[AS3] 變數預設值


※ 以var陳述式宣告變數之後,初始化賦值之前,變數依其宣告時之資料型態會有不同之預設值。
※ 未初始化的變數依其資料型態不同所包含預設值,如下:





資料類型
預設值
Boolean
false
int
0
Number
NaN
Object
null
String
null
uint
0
未宣告 (相當於類型註釋 *)
undefined
所有其它類別,包括使用者定義的類別。
null


變數宣告為 Boolean、Number、int 和 uint 以外的資料類型,其未初始化的預設值都是 null。
不論AS3定義或自訂義的類別皆如此。
未宣告資料類型 (相當於類型註釋 *)則為undefined。

2011年7月17日 星期日

函數運算式的特性


學習 ActionScript 3.0 / ActionScript 語言和語法 / 函數

適用於 Adobe  Flash  Professional CS5 的 ActionScript  3.0 參考__最上層__●Function

一、函數運算式有時又稱為函數常值或匿名函數
二、var 函數名稱:Function = function(參數,...){函數主體}
三、函數運算式不能獨自存在,通常是指定陳述式的一部分
四、在嚴謹模式中,不能使用點語法叫用函數運算式宣告的方法
五、函數運算式更適合用來進行著重執行階段或動態行為方式的程式設計
六、若偏好使用嚴謹模式,但也需要呼叫用函數運算式宣告的方法 :
A. 使用方括號 ([]) 而不使用點 (.) 運算子來呼叫方法,如,myInstance["methodExpression()"]();
B. 將整個類別宣告為動態類別,這樣可以讓您使用點運算子呼叫方法
七、在特定情況下,函數運算式很有用。函數運算式的其中一個常用用法,就是供只用一次就捨棄的函數使用
八、在記憶體管理和記憶體回收方面,函數運算式不會做為物件獨立存在。換句話說,當您將函數運算式指定至另一個物件 (例如陣列元素或物件屬性) 時,您在程式碼中建立該函數運算式的唯一參考。若函數運算式所附加的陣列或物件超出範圍,或是因其它原因無法再使用,您無法再存取該函數運算式。若刪除該陣列或物件,函數運算式所使用的記憶體可供進行記憶體回收,也就是說,該記憶體可開始回收,重新做為其它用途。
九、就函數運算式而言,一旦刪除了運算式所指定的屬性,就不能再使用該函數 (delete)
十、如果函數先用函數陳述式加以定義,則可以做為自身的物件而存在,而且即使刪除所附加的屬性之後,也會繼續存在。delete 運算子只會針對物件的屬性作用,因此即使是刪除函數 stateFunc() 本身的呼叫也沒有作用。
十一、函數陳述式在所定義的範圍中一直都存在,包括出現在函數陳述式之前的陳述式中。對照之下,函數運算式則只為後續陳述式定義。函數運算式在定義之前無法使用。

2011年7月16日 星期六

動態產生函數運算式及以Delete刪除

※ 動態建立函數運算式,以trace()觀察this在函數運算式內部與外部的不同
※ 對於繫結方法,this 關鍵字會指向實作該方法的原始物件。 對於函數來說,this 則會在叫用該函數時指向關聯物件。
※ 此例,在top.aFunc 函數運算式內部trace(this)則this指向top的類別物件[object MovieClip] ; trace(this.name)則指向top的name屬性topMC ; 在top.aFunc 函數運算式外部trace(this)則指向[object MainTimeline]
※ 動態產生的函數可被delete刪除
在元件庫內,AAA是個圓形MovieClip,綁定AAA內建資源類別

1000715_function_test_1.swf


var top:MovieClip = addChild(new MovieClip()) as MovieClip;
top.name = "topMC";

/*動態建立函式運算式*/
top.aFunc = function():DisplayObject{
trace("----------------------------------");
trace("@@@在top.aFunc()之內的trace");

/*以下這兩行雖然是trace(),但都會先new出AAA的實體,再trace出來*/
trace("@top.aFunc() / addChild(new AAA()) : " + addChild(new AAA())); //[object AAA]
trace("@top.aFunc() / getQualifiedClassName(addChild(new AAA())) : " + getQualifiedClassName(addChild(new AAA()))); //AAA

/*1118: 靜態類型 flash.display:DisplayObject 的值
以隱含方式強制轉型成可能不相關的類型 AAA。*/
/*var aaa:AAA = addChild(new AAA());*/

/*以下這行可以*/
/*var aaa:AAA = addChild(new AAA()) as AAA;*/

var aaa:AAA = this["addChild"](new AAA());
aaa.x=aaa.y=200;

/*this 會在此函數(top.aFunc()函數) 被叫用時,指向關聯物件*/
/*top.aFunc()函數 - 動態建立給top實體的函數運算式*/
trace("@top.aFunc() / this : " + this); /*[object MovieClip]*/
trace("@top.aFunc() / this.name : " + this.name); //topMC
trace("@top.aFunc() / getQualifiedClassName(this) : " + getQualifiedClassName(this)); //flash.display::MovieClip
trace("@top.aFunc() / getQualifiedSuperclassName(this) : " + getQualifiedSuperclassName(this)); //flash.display::Sprite
trace("----------------------------------");

return aaa;
}


trace("----------------------------------");
trace("@@@在top.aFunc()之外的trace");
trace("@this : " + this); //[object MainTimeline]
trace("@this.name : " + this.name); //root1
trace("getQualifiedClassName(this) : " + getQualifiedClassName(this)); //_1000715_function_test_1_fla::MainTimeline
trace("getQualifiedSuperclassName(this) : " + getQualifiedSuperclassName(this)); //flash.display::MovieClip
trace("----------------------------------");

trace("top.aFunc : " + top.aFunc); //function Function() {}
/*在以下這行會先調用了top.aFunc(),之後才trace出來*/
trace("※※※top.aFunc() : " + top.aFunc()); //[object AAA]
/*top.aFunc();*/
trace("----------------------------------");

/*delete 動態產生的top.aFunc 函數運算式*/
delete top.aFunc;
trace("@@@在delete top.aFunc之後的trace");
/*top.aFunc = null;*/
trace("top.aFunc : " + top.aFunc); //undefined
/*底下這行會先調用top.aFunc(),之後再trace出來*/
trace("top.aFunc() : " + top.aFunc()); //TypeError: Error #1006: aFunc 不是函數。at _1000715_function_test_1_fla::MainTimeline/frame1()
/*top.aFunc();*/