關聯陣列

Flash Player 9 以及更新的版本,Adobe AIR 1.0 以及更新的版本

關聯陣列有時也稱為「雜湊」或「對應」,它會使用「索引鍵」而非數值索引來組織儲存的值。關聯陣列中的每個索引鍵都是唯一的字串,可用來存取儲存的值。關聯陣列是 Object 類別的實體,也就是說,每個索引鍵都會對應到一個屬性名稱。關聯陣列是索引鍵與值配對的無順序集合。程式碼不應該寄望關聯陣列的索引鍵會有一定的順序。

ActionScript 3.0 也包括名為「字典」的進階類型關聯陣列。字典是 Dictionary 類別在 flash.utils 套件中的實體,它所使用的索引鍵可以是任何資料類型。換句話說,字典的索引鍵不限於 String 類型的值。

具有字串索引鍵的關鍵陣列

有兩種方式可以在 ActionScript 3.0 中建立關聯陣列,第一種方式是使用 Object 實體。使用 Object 實體,您即可以物件常值初始化陣列。Object 類別的實體 (也稱為一般物件) 在功能上和關聯陣列完全相同。一般物件的每個屬性名稱都能當做索引鍵,可用來存取儲存的值。

下列範例會建立名為 monitorInfo 的關聯陣列,並使用物件常值搭配兩個索引鍵和值配對來初始化這個陣列:

var monitorInfo:Object = {type:"Flat Panel", resolution:"1600 x 1200"}; 
trace(monitorInfo["type"], monitorInfo["resolution"]);  
// output: Flat Panel 1600 x 1200

如果您不需要在宣告階段初始化陣列,則可以使用 Object 建構函式來建立陣列,如下所示:

var monitorInfo:Object = new Object();

使用物件常值或 Object 類別建構函式建立陣列之後,您可以使用陣列存取 ( [] ) 運算子或點運算子 ( . )。 下列範例會將兩個新的值加入 monitorArray

monitorInfo["aspect ratio"] = "16:10"; // bad form, do not use spaces 
monitorInfo.colors = "16.7 million"; 
trace(monitorInfo["aspect ratio"], monitorInfo.colors); 
// output: 16:10 16.7 million

請注意,名為 aspect ratio 的索引鍵包含空格字元。這對於陣列存取 ( [] ) 運算子是可行的,但要是使用點運算子,就會產生錯誤。因此,建議您不要在索引鍵名稱中使用空格。

第二種建立關聯陣列的方式就是使用 Array 建構函式 (或任何動態類別的建構函式),然後再使用陣列存取 ( [] ) 運算子或點運算子 ( . ),將索引鍵與值配對加入陣列中。如果將關聯陣列宣告為 Array 類型,就無法使用物件常值來初始化陣列。下列範例會使用 Array 建構函式來建立名為 monitorInfo 的關聯陣列,然後將 type 索引鍵和 resolution 索引鍵,連同其各自的值一併加入該陣列中:

var monitorInfo:Array = new Array(); 
monitorInfo["type"] = "Flat Panel"; 
monitorInfo["resolution"] = "1600 x 1200"; 
trace(monitorInfo["type"], monitorInfo["resolution"]);  
// output: Flat Panel 1600 x 1200

使用 Array 建構函式來建立關聯陣列,並不具備任何優勢。即使您使用 Array 建構函式或 Array 資料類型,也無法搭配關聯陣列使用 Array.length 屬性或任何 Array 類別的方法。由此可見,Array 建構函式最適合用來建立索引陣列。

具有物件索引鍵的關聯陣列 (字典)

您可以使用 Dictionary 類別來建立關聯陣列,此陣列會使用物件而非字串做為索引鍵。這種陣列有時也稱為字典、雜湊或對應。舉例來說,就好比一個應用程式可以根據 Sprite 物件與特定容器的關聯來找到該物件的位置一樣。您可以使用 Dictionary 物件,將每個 Sprite 物件對應到容器。

下列程式碼會建立 Sprite 類別的三個實體,做為 Dictionary 物件的索引值。在程式碼中,會為每個索引鍵分別指定 GroupA GroupB 的值。這些值可以是任何資料類型,但是在本範例中, GroupA GroupB 都是 Object 類別的實體。接著,您可以使用陣列存取 ( [] ) 運算子,存取和每個索引鍵相關聯的值,如下列程式碼所示:

import flash.display.Sprite; 
import flash.utils.Dictionary; 
 
var groupMap:Dictionary = new Dictionary(); 
 
// objects to use as keys 
var spr1:Sprite = new Sprite(); 
var spr2:Sprite = new Sprite(); 
var spr3:Sprite = new Sprite(); 
 
// objects to use as values 
var groupA:Object = new Object(); 
var groupB:Object = new Object(); 
 
// Create new key-value pairs in dictionary. 
groupMap[spr1] = groupA; 
groupMap[spr2] = groupB; 
groupMap[spr3] = groupB; 
 
if (groupMap[spr1] == groupA) 
{ 
    trace("spr1 is in groupA");  
} 
if (groupMap[spr2] == groupB) 
{ 
    trace("spr2 is in groupB");  
} 
if (groupMap[spr3] == groupB) 
{ 
    trace("spr3 is in groupB");  
}

重複物件索引鍵

您可以使用 for..in 迴圈或 for each..in 迴圈,重複執行 Dictionary 物件的內容。 for..in 迴圈可以讓您根據索引鍵來重複執行,而 for each..in 迴圈則可以讓您根據與每個索引鍵相關聯的值來重複執行。

您可以使用 for..in 迴圈,直接存取 Dictionary 物件的物件索引鍵。您也可以使用陣列存取 ( [] ) 運算子,存取 Dictionary 物件的值。下列程式碼會使用之前的 groupMap 字典範例,顯示如何以 for..in 迴圈重複執行 Dictionary 物件:

for (var key:Object in groupMap) 
{ 
    trace(key, groupMap[key]); 
} 
/* output: 
[object Sprite] [object Object] 
[object Sprite] [object Object] 
[object Sprite] [object Object] 
*/

您可以使用 for each..in 迴圈,直接存取 Dictionary 物件的值。下列程式碼也會使用 groupMap 字典,說明如何以 for each..in 迴圈重複執行 Dictionary 物件:

for each (var item:Object in groupMap) 
{ 
    trace(item); 
} 
/* output: 
[object Object] 
[object Object] 
[object Object] 
*/

物件索引鍵和記憶體管理

Adobe® Flash® Player 和 Adobe® AIR™ 都會使用記憶體回收系統,復原不再使用的記憶體。當物件沒有指向本身的參考時,即可進行記憶體回收,而記憶體將在下次記憶體回收系統執行時復原。例如,下列程式碼會建立新的物件,並且將物件的參考指定給 myObject 變數:

var myObject:Object = new Object();

只要有任何物件的參考存在,記憶體回收系統就不會復原該物件所佔用的記憶體。如果變更 myObject 的值使它指向不同的物件,或是設定為 null 值,原始物件所佔的記憶體就可以進行記憶體回收,但前提是,該原始物件已沒有其它參考。

如果您將 myObject 當做 Dictionary 物件中的索引鍵,表示您正為原始物件建立另一個參考。例如,下列程式碼會為物件建立兩個參考,它們分別是 myObject 變數以及 myMap 物件中的索引鍵:

import flash.utils.Dictionary; 
 
var myObject:Object = new Object(); 
var myMap:Dictionary = new Dictionary(); 
myMap[myObject] = "foo";

若要使 myObject 所參考的物件可進行記憶體回收,您必須移除該物件的所有參考。在這種情況下,您必須變更 myObject 的值,並刪除 myMap 中的 myObject 索引鍵,如下列程式碼所示:

myObject = null; 
delete myMap[myObject];

或者,您也可以使用 Dictionary 建構函式的 useWeakReference 參數,將所有的字典索引鍵變成「弱參考」。記憶體回收系統會忽略弱參考,這表示只具有弱參考的物件可以進行記憶體回收。例如在下列程式碼中,您不需要為了使物件可進行記憶體回收而刪除 myMap 中的 myObject 索引鍵:

import flash.utils.Dictionary; 
 
var myObject:Object = new Object(); 
var myMap:Dictionary = new Dictionary(true); 
myMap[myObject] = "foo"; 
myObject = null; // Make object eligible for garbage collection.