Flashゲームプログラミング講座 for ActionScript3.0

 

Object クラスについて

 


■Object クラスについて


Object クラスは、連想配列用のクラスです。
 
ユニーク(唯一)な文字列をキーにして、好きなデータを格納する事ができます。
 
Object クラスは、すべてのオブジェクトの原型となります。
 

■データ型の種類について

 
データの型には、プリミティブ型と、リファレンス型があります。
 
■プリミティブ型について
 
プリミティブ型は、基本的で単純なデータ型です。
 
null、undefined、Boolean、Number、String 型が該当します。
 
■リファレンス型について
 
リファレンス型は、複合的なデータ型です。
 
Object、Array、Function 型など、すべてのオブジェクトが該当します。
 
リファレンス型については、こちらで解説しています。
 


 

オブジェクトを作成する

 
 


■Object オブジェクトを作成する

 
new 演算子を使って、Object クラスをインスタンス化します。
 
ActionScript 3.0 では、Object コンストラクタの引数から、値情報 [[PrimitiveValue]] を指定する事はできません。
 
ActionScript 2.0 以前の場合は、こちらで解説しています。
 
■作成例
 
空のオブジェクトを作成する

// 空の Object オブジェクトを作成する
var obj:Object = new Object();

// 出力テスト
trace(obj);
 

■初期データを格納しつつ Object オブジェクトを作成する

 
■オブジェクトリテラルを使用する
 
中括弧 { } の中に、キー:データ と記述します。
 
キーに指定する名称は、変数の命名規則に従う必要があります。
 
複数のデータを格納したい場合は、カンマ , で区切ります。
 
この書式を、オブジェクトリテラルといいます。
 
空の Object オブジェクトを作成する

// 空の Object オブジェクトを作成する
var obj:Object = { };

// 出力テスト
trace(obj);
 
オブジェクトリテラルを使って、Object オブジェクトを作成する

// ------------------------------------------------------------
// オブジェクトリテラルを使って、Object オブジェクトを作成する
// ------------------------------------------------------------
var obj:Object = { aaaaa:null , bbbbb:true , ccccc:123 , ddddd:"あいうえお" };

// ------------------------------------------------------------
// 出力テスト(ドットアクセス演算子を使ってアクセス)
// ------------------------------------------------------------
trace(obj.aaaaa); // null
trace(obj.bbbbb); // false
trace(obj.ccccc); // 123
trace(obj.ddddd); // "あいうえお"
 
■キーをダブルクォーテーションで括った場合
 
ActionScript 3.0 では、キーは、ダブルコーテーション "" で括ることができます。
 
キーをダブルクォーテーションで括った場合、変数の命名規則に従う必要はありません。
 
全角や数値などのすべての文字を、キーとして使用することができます。
 
オブジェクトリテラルを使って、Object オブジェクトを作成する(キーをダブルクォーテーションで括る)

// ------------------------------------------------------------
// オブジェクトリテラルを使って、Object オブジェクトを作成する
// ------------------------------------------------------------
var obj:Object = { "添字1":null , "添字2":true , "添字3":123 , "添字4":"あいうえお" };

// ------------------------------------------------------------
// 出力テスト(配列アクセス演算子を使ってアクセス)
// ------------------------------------------------------------
trace(obj["添字1"]); // null
trace(obj["添字2"]); // false
trace(obj["添字3"]); // 123
trace(obj["添字4"]); // "あいうえお"
 

■オブジェクトの任意のプロパティにアクセスする

 
オブジェクトの任意のプロパティにアクセスするには、ドットアクセス演算子か、配列アクセス演算子を使用します。
 
アクセスしたプロパティに、データが存在しない場合は、undefined 値が得られます。
 
■ドットアクセス演算子を使用する
 
ドットアクセス演算子は、Object.キー と記述します。
 
キーの名称は、変数の命名規則に従う必要があります。
 
ドットアクセス演算子を使って、任意のプロパティにアクセスする

var v:*;
var key:String;

// ------------------------------------------------------------
// オブジェクトを作成する
// ------------------------------------------------------------
var obj:Object = {
	aaaaa:null,
	bbbbb:true,
	ccccc:123,
	ddddd:"あいうえお"
};

// ------------------------------------------------------------
// 任意のプロパティに読み取りアクセスする
// ------------------------------------------------------------
// aaaaa プロパティからデータを取得
v = obj.aaaaa;

// 出力テスト
trace(v); // null

// ccccc プロパティからデータを取得
v = obj.ccccc;

// 出力テスト
trace(v); // 123


// ------------------------------------------------------------
// 任意のプロパティに書き込みアクセスする
// ------------------------------------------------------------
// bbbbb プロパティにデータをセット
obj.bbbbb = false;

// eeeee プロパティにデータをセット
obj.eeeee = "かきくけこ";


// ------------------------------------------------------------
// 出力テスト { aaaaa:null , bbbbb:false , ccccc:123 , ddddd:"あいうえお" , eeeee:"かきくけこ" }
// ------------------------------------------------------------
for (key in obj){
	trace("---");
	trace("key:"  + key);
	trace("data:" + obj[key]);
}
 
■配列アクセス演算子を使用する
 
配列アクセス演算子は、Object["キー"] と記述します。
 
キーの名称は、変数の命名規則に従う必要はありません。
 
配列アクセス演算子を使用すると、プロパティ名の指定を動的に制御する事ができます。
 
配列アクセス演算子を使って、任意のプロパティにアクセスする

var v:*;
var key:String;

// ------------------------------------------------------------
// オブジェクトを作成する
// ------------------------------------------------------------
var obj:Object = {
	"添字1":null,
	"添字2":true,
	"添字3":123,
	"添字4":"あいうえお"
};


// ------------------------------------------------------------
// 任意のプロパティに読み取りアクセスする
// ------------------------------------------------------------
// "添字1" プロパティからデータを取得
v = obj["添字1"];

// 出力テスト
trace(v); // null

// "添字3" プロパティからデータを取得
key = "添字3";
v = obj[key];

// 出力テスト
trace(v); // 123


// ------------------------------------------------------------
// 任意のプロパティに書き込みアクセスする
// ------------------------------------------------------------
// "添字2" プロパティにデータをセット
obj["添字2"] = false;

// "添字5" プロパティにデータをセット
key = "添字5";
obj[key] = "かきくけこ";


// ------------------------------------------------------------
// 出力テスト { "添字1":null , "添字2":false , "添字3":123 , "添字4":"あいうえお" , "添字5":"かきくけこ" }
// ------------------------------------------------------------
for (key in obj){
	trace("---");
	trace("key:"  + key);
	trace("data:" + obj[key]);
}
 

■オブジェクトのすべてのプロパティに順番にアクセスする

 
■ for..in 文を使用する
 
for..in 文を使って、アクセスする例です。
 
プロパティ名を取得できるので、配列アクセス演算子を使ってデータにアクセスします。
 
for..in 文を使用して、すべてのプロパティのデータに順番にアクセスする

// ------------------------------------------------------------
// オブジェクトを作成する
// ------------------------------------------------------------
var obj:Object = {
	aaa:null,
	bbb:true,
	ccc:123,
	ddd:"あいうえお"
};

// ------------------------------------------------------------
// for..in 文を使用して、すべてのプロパティのデータに順番にアクセスする
// ------------------------------------------------------------
var key:String;
for (key in obj){
	trace("---");
	trace("key:"  + key);
	trace("data:" + obj[key]);
}
 

■オブジェクトの任意のプロパティを削除する

 
オブジェクトの任意のプロパティを削除するには、delete 文を使用します。
 
オブジェクトの任意のプロパティを削除する

// ------------------------------------------------------------
// オブジェクトを作成する
// ------------------------------------------------------------
var obj:Object = {
	aaa:null,
	bbb:true,
	ccc:123,
	ddd:"あいうえお"
};

// ------------------------------------------------------------
// オブジェクトの任意のプロパティを削除する
// ------------------------------------------------------------
// aaa プロパティを削除する
delete obj.aaa;

// ccc プロパティを削除する
delete obj["ccc"];

// ------------------------------------------------------------
// 残っているプロパティをすべて出力する { bbb:true , ddd:"あいうえお" }
// ------------------------------------------------------------
var key:String;
for (key in obj){
	trace("---");
	trace("key:"  + key);
	trace("data:" + obj[key]);
}
 


 

オブジェクトツリーを構築する

 


■オブジェクトツリーを構築する

 
■オブジェクトツリーを構築するには?
 
Object クラスは、連想配列用のクラスです。
 
Object オブジェクト1つだけでは、木構造の階層を構築する事はできません。
 
Object オブジェクトは、ノード(節)1つとして利用できます。
 
オブジェクトの各プロパティに、必要な数だけ Object オブジェクトを作成して格納します。
 
例えば、2段の階層を持つオブジェクトツリーを構築する例です。
 
オブジェクトツリーを構築するには、オブジェクトの各プロパティに Object オブジェクトを作成して格納する

// オブジェクトを作成する(ルートに相当)
var obj:Object = new Object();

// オブジェクトの各プロパティに、オブジェクトを作成して格納する(ノードに相当)
obj.aaa = new Object();
obj.bbb = new Object();
obj.ccc = new Object();
 
 
■オブジェクトツリーを初期化する
 
オブジェクトツリーの初期化は、オブジェクトリテラルで記述すると、視覚的に見やすくなります。
 
オブジェクトリテラルを使って、複雑なオブジェクトツリーを構築する

var obj:Object = {
	aaa:{
		count:123,
		name:"テスト1",
		result:false
	},
	bbb:{
		count:456,
		name:"テスト2",
		result:true
	},
	ccc:{
		count:789,
		name:"テスト3",
		param:{
			ary:["a","b","c"],
			name:"テスト4"
		},
		result:true
	}
};
 
 
■オブジェクトツリー内の任意のプロパティにアクセスする
 
オブジェクトツリー内の任意のプロパティにアクセスするには、ドットアクセス演算子か、配列アクセス演算子を使用します。
 
2段の階層を持つオブジェクトツリーにアクセスする

// ------------------------------------------------------------
// 2段の階層を持つオブジェクトツリーを作成する
// ------------------------------------------------------------
// オブジェクトを作成する(ルートに相当)
var obj:Object = new Object();

// オブジェクトの各プロパティに、オブジェクトを作成して格納する(ノードに相当)
obj.aaa = new Object();
obj.bbb = new Object();
obj.ccc = new Object();


// ------------------------------------------------------------
// 任意のプロパティに書き込みアクセスする
// ------------------------------------------------------------
// ドットアクセス演算子を使ってデータをセットする
obj.aaa.ddd = "D";

// 配列アクセス演算子を使ってデータをセットする
obj["ccc"]["eee"] = "E";


// ------------------------------------------------------------
// 任意のプロパティに読み取りアクセスする
// ------------------------------------------------------------
var v:*;

// ドットアクセス演算子を使ってデータを取得する
v = obj.aaa.ddd;

// 出力テスト
trace(v); // "D"

//配列アクセス演算子を使ってデータを取得する
v = obj["ccc"]["eee"];

// 出力テスト
trace(v); // "E"
 


 

Object クラスのプロパティについて

 


■Object クラスのプロパティ


Object クラスには、以下のプロパティがあります。(一部抜粋)
 
プロパティ 説明
constructor Function 自身が実体化された時に使われた、コンストラクタ関数を取得します。
 
 


■ constructor プロパティ


コンストラクタ関数を使って、オブジェクトを生成することができます。
 
コンストラクタ関数については、こちらで解説しています。
 
実体化に使われたコンストラクタ関数を取得するには、constructor プロパティを使用します。
 
配列オブジェクトのコンストラクタ関数を調べる

// Array オブジェクトを作成する
var ary:Array = new Array();

// コンストラクタ関数が一致するか調べる
trace(ary.constructor == Array); // true
 
MyFunc オブジェクトのコンストラクタ関数を調べる

// ------------------------------------------------------------
// MyFunc という名前の関数を宣言する
// ------------------------------------------------------------
function MyFunc ():void{
}

// ------------------------------------------------------------
// MyFunc オブジェクトを作成する
// ------------------------------------------------------------
var obj:Object = new MyFunc();

// コンストラクタ関数が一致するか調べる
trace(obj.constructor == MyFunc); // true
 
■オブジェクトがプロトタイプチェーンである場合
 
constructor プロパティは、必ずしも正しい情報が得られるとは限りません。
 
constructor プロパティは、自身のオブジェクトが所有している訳ではありません。
 
コンストラクタ関数にデフォルトでセットされている、プロトタイプが所有しています。
 
prototype プロパティを変更してから、コンストラクタ関数を実体化した場合、自身の constructor プロパティの情報は失われている事に注意してください。
 
プロトタイプチェーンであるオブジェクトの constructor プロパティを調べる

// ------------------------------------------------------------
// MyFunc_A という名前の関数を宣言する
// ------------------------------------------------------------
function MyFunc_A():void{
}

// ------------------------------------------------------------
// MyFunc_B という名前の関数を宣言する
// ------------------------------------------------------------
function MyFunc_B():void{
}

// ------------------------------------------------------------
// 関数にデフォルトでセットされている、プロトタイプオブジェクトを取得する
// ------------------------------------------------------------
var prototype_a:Object = MyFunc_A.prototype;
var prototype_b:Object = MyFunc_B.prototype;

// 出力テスト
trace(prototype_a.constructor === MyFunc_A); // true
trace(prototype_b.constructor === MyFunc_B); // true


// ------------------------------------------------------------
// MyFunc_B オブジェクトを作成する(Object → MyFunc_B)
// ------------------------------------------------------------
var obj0:Object = new MyFunc_B();

// コンストラクタ関数が一致するか調べる
trace(obj0.constructor === MyFunc_B); // true

// ------------------------------------------------------------
// MyFunc_B 関数を実体化した時に、インスタンスのプロトタイプとなるオブジェクトを指定する
// ------------------------------------------------------------
MyFunc_B.prototype = new MyFunc_A();

// ------------------------------------------------------------
// MyFunc_B オブジェクトを作成する(Object → MyFunc_A → MyFunc_B)
// ------------------------------------------------------------
var obj1:Object = new MyFunc_B();

// コンストラクタ関数が一致するか調べる
trace(obj1.constructor === MyFunc_B); // false( MyFunc_B.prototype を変更したので本来の情報が失われた)
trace(obj1.constructor === MyFunc_A); // true (プロトタイプチェーンを巡って次に得られる情報)
 


 

Object クラスのメソッドについて

 


■Object クラスのメソッド


Object クラスには、以下のメソッドがあります。(一部抜粋)
 
メソッド 説明
toString() オブジェクトから文字列情報を取得する。
valueOf() オブジェクトから値情報を取得する。
hasOwnProperty() 指定したプロパティ名が存在するか調べる。
isPrototypeOf() 自身が、指定オブジェクトのプロトタイプチェーン内に含まれるか調べる。
setPropertyIsEnumerable() 指定したプロパティ名の列挙の有無を設定する。(for..in 文などで検出されるか)
propertyIsEnumerable() 指定したプロパティ名の列挙の有無を調べる。
 
 


■ toString() メソッド


オブジェクトから、文字列情報を取得するには、toString() メソッドを使用します。
 
日付オブジェクトから、文字列情報を取得する

// Date オブジェクトを作成する
var date_obj:Date = new Date();

// 出力テスト
trace(date_obj.toString());
 
■オーバーライドについて
 
toString() メソッドを、オーバーライドする事ができます。
 
toString プロパティを追加し、コールバック関数を登録します。
 
コールバック関数の戻り値から、好きな文字列を返します。
 
オブジェクトに、データの読み取りが試みられた場合、まず valueOf() メソッドが実行されます。
 
valueOf() メソッドから、自身のオブジェクトを返した場合、値情報無しを意味します。
 
オブジェクトに値情報が存在しなかった場合、次に toString() メソッドが実行されます。
 
文字列型として読み取られる場合、直接 toString() メソッドが実行される事もあります。
 
toString メソッドをオーバーライドする

// ------------------------------------------------------------
// 空のオブジェクトを作成する
// ------------------------------------------------------------
var obj:Object = new Object();

// ------------------------------------------------------------
// valueOf メソッドをオーバーライドする
// ------------------------------------------------------------
obj.valueOf = function ():*{

	trace("valueOf が呼び出された");

	// 自身のオブジェクトを返した場合、値情報無しを意味する
	return this;
};

// ------------------------------------------------------------
// toString メソッドをオーバーライドする
// ------------------------------------------------------------
obj.toString = function ():String{

	trace("toString が呼び出された");

	return "オーバーライド";
};

// ------------------------------------------------------------
// 数値を足す(オブジェクトが読み取られる)
// ------------------------------------------------------------
var str:String = 12345 + obj;

// 出力テスト
trace(str); // "12345オーバーライド"
 

■ valueOf() メソッド


オブジェクトから、値情報を取得するには、valueOf() メソッドを使用します。
 
自身のオブジェクトが得られた場合、値情報が存在しない事を意味します。
 
Object オブジェクトから値情報を取得する

// Object オブジェクトを作成する
var obj:Object = new Object();

// 出力テスト(自身のオブジェクトが得られたので値情報は存在しない)
trace(obj.valueOf() == obj); // true
 
日付オブジェクトから値情報を取得する

// Date オブジェクトを作成する
var date_obj:Date = new Date();

// 出力テスト
trace(date_obj.valueOf());
 
■オーバーライドについて
 
valueOf() メソッドを、オーバーライドする事ができます。
 
valueOf プロパティを追加し、コールバック関数を登録します。
 
コールバック関数の戻り値から、好きなデータを返します。
 
自身のオブジェクトを返した場合、値情報無しを意味します。
 
オブジェクトに、読み取りが試みられた場合、valueOf() メソッドが実行されます。
 
オーバーライドを終了する場合、delete 文を使って、valueOf プロパティを削除します。
 
valueOf メソッドをオーバーライドする

// ------------------------------------------------------------
// Number オブジェクトを作成する
// ------------------------------------------------------------
var obj:Object = new Object();

// ------------------------------------------------------------
// valueOf メソッドをオーバーライドする
// ------------------------------------------------------------
obj.valueOf = function ():*{

	trace("valueOf が呼び出された");

	return 987;
};

// ------------------------------------------------------------
// 数値を足す(オブジェクトが読み取られる)
// ------------------------------------------------------------
var v:Number = 0 + obj;

// 出力テスト
trace(v); // 987

// ------------------------------------------------------------
// 数値として比較する(オブジェクトが読み取られる)
// ------------------------------------------------------------
if(obj > 0){
}

// ------------------------------------------------------------
// オーバーライドを終了する
// ------------------------------------------------------------
delete obj.valueOf;
 

■ hasOwnProperty() メソッド

 
オブジェクトに、指定したプロパティ名が存在するか調べるには、hasOwnProperty() メソッドを使用します。
 
Object.hasOwnProperty ( "プロパティ名" ) :Boolean
第01引数 Stringプロパティ名を文字列で指定
戻り値 Booleanプロパティが存在する場合 true、存在しない場合 false が得られる。
 
指定したプロパティ名が存在するか調べる

// オブジェクトを作成する
var obj:Object = new Object();

// プロパティを追加する
obj.aaa = "a";

// 出力テスト
trace(obj.hasOwnProperty("aaa")); // true
trace(obj.hasOwnProperty("bbb")); // false
 

■ isPrototypeOf() メソッド

 
自身が、指定オブジェクトのプロトタイプチェーン内に含まれるか調べるには、isPrototypeOf() メソッドを使用します。
 
このメソッドは、プロトタイプオブジェクトから呼び出します。
 
Object.isPrototypeOf ( オブジェクト ) :Boolean
第01引数 Objectインスタンス側のオブジェクトを指定。
戻り値 Booleanプロトタイプである場合 true、該当しない場合 false が得られる。
 
配列オブジェクトのプロトタイプを確認する

// 配列オブジェクトを作成する
var ary:Array = new Array();

// Array コンストラクタから、プロトタイプオブジェクトを取得する
var prototype_obj:Object = Array.prototype;

// 出力テスト
trace(prototype_obj.isPrototypeOf(ary)); // true
 
プロトタイプチェーン状態にあるインスタンスのプロトタイプを確認する

// ------------------------------------------------------------
// MyFunc_A という名前の関数を宣言する
// ------------------------------------------------------------
function MyFunc_A ():void{
}

// ------------------------------------------------------------
// MyFunc_B という名前の関数を宣言する
// ------------------------------------------------------------
function MyFunc_B ():void{
}

// ------------------------------------------------------------
// MyFunc_C という名前の関数を宣言する
// ------------------------------------------------------------
function MyFunc_C ():void{
}

// ------------------------------------------------------------
// プロトタイプチェーン関係を構築する
// ------------------------------------------------------------
// MyFunc_A オブジェクトを作成する
var obj_a:Object = new MyFunc_A();

// MyFunc_B のプロトタイプにセットする
MyFunc_B.prototype = obj_a;

// MyFunc_B オブジェクトを作成する
var obj_b:Object = new MyFunc_B();

// MyFunc_C のプロトタイプにセットする
MyFunc_C.prototype = obj_b;

// ------------------------------------------------------------
// MyFunc_C オブジェクトを作成する
// ------------------------------------------------------------
var obj_c:Object = new MyFunc_C();

// ------------------------------------------------------------
// 出力テスト
// ------------------------------------------------------------
trace(obj_a.isPrototypeOf(obj_a)); // false
trace(obj_a.isPrototypeOf(obj_b)); // true
trace(obj_a.isPrototypeOf(obj_c)); // true

trace(obj_b.isPrototypeOf(obj_a)); // false
trace(obj_b.isPrototypeOf(obj_b)); // false
trace(obj_b.isPrototypeOf(obj_c)); // true

trace(obj_c.isPrototypeOf(obj_a)); // false
trace(obj_c.isPrototypeOf(obj_b)); // false
trace(obj_c.isPrototypeOf(obj_c)); // false
 

■ setPropertyIsEnumerable() メソッド

 
指定したプロパティ名の、列挙の有無を設定するには、setPropertyIsEnumerable() メソッドを使用します。
 
列挙を禁止すると、for..in 文などで検出できなくなります。
 
Object.setPropertyIsEnumerable ( "プロパティ名" , 列挙可能か? ) :void
第01引数 Object設定したいプロパティ名を指定。
第01引数(略可)Boolean列挙を許可するなら true。列挙を禁止するなら false を指定。(デフォルトは true)
戻り値 voidなし。
 
プロパティの列挙の有無を設定する

// ------------------------------------------------------------
// オブジェクトを作成する
// ------------------------------------------------------------
var obj:Object = new Object();

// ------------------------------------------------------------
// プロパティを追加する
// ------------------------------------------------------------
obj.aaa = "a";
obj.bbb = "b";
obj.ccc = "c";
obj.ddd = "d";
obj.eee = "e";

// ------------------------------------------------------------
// プロパティの列挙の有無を設定する
// ------------------------------------------------------------
obj.setPropertyIsEnumerable("aaa",false );
obj.setPropertyIsEnumerable("bbb",true  );
obj.setPropertyIsEnumerable("ccc",false );
obj.setPropertyIsEnumerable("ddd",false );
obj.setPropertyIsEnumerable("eee",true  );


// ------------------------------------------------------------
// 出力テスト "bbb" , "eee"
// ------------------------------------------------------------
var key:String;
for (key in obj){
	trace(key);
}
 

■ propertyIsEnumerable() メソッド

 
指定したプロパティ名の、列挙の有無を調べるには、propertyIsEnumerable() メソッドを使用します。
 
Object.propertyIsEnumerable ( "プロパティ名" ) :Boolean
第01引数 Object調べたいプロパティ名を指定。
戻り値 Boolean列挙可能であれば true、列挙禁止であれば false が得られる。
 
プロパティの列挙の有無を取得する

// ------------------------------------------------------------
// オブジェクトを作成する
// ------------------------------------------------------------
var obj:Object = new Object();

// ------------------------------------------------------------
// プロパティを追加する
// ------------------------------------------------------------
obj.aaa = "a";
obj.bbb = "b";

// ------------------------------------------------------------
// プロパティの列挙の有無を設定する
// ------------------------------------------------------------
obj.setPropertyIsEnumerable("aaa",false );
obj.setPropertyIsEnumerable("bbb",true  );

// ------------------------------------------------------------
// プロパティの列挙の有無を調べる
// ------------------------------------------------------------
trace(obj.propertyIsEnumerable("aaa")); // false
trace(obj.propertyIsEnumerable("bbb")); // true
 


 

Object クラスのデータ管理について

 
 


■Object オブジェクトを辞書として使用する

 
Object オブジェクトは、文字列をキーとした辞書として取り扱う事ができます。
 
ActionScript 3.0 では、辞書機能に特化した、Dictionary クラスもあります。
 
■辞書として取り扱う理由
 
Object オブジェクトは、内部でハッシュテーブルを使った高速化が実現されています
 
文字列をキーとして指定することで、該当するデータを高速で検索する事ができます。
 
また、すべてのデータの中から該当するデータが存在しない事を、高速で判別する事もできます。
 
データの総数が、100 万以上ある場合でも、瞬時に検索できます。
 
■辞書として管理するためには?
 
データごとに、ユニーク(唯一)な識別名が、存在している必要があります。
 
例えば、以下の様なアドレス情報は、辞書として管理することができます。
 
辞書として管理するためには、データごとにユニークな識別名が必要

var page_a:Object = { url:"http://example.com/a.html", title:"タイトルA", size:1310 };
var page_b:Object = { url:"http://example.com/b.html", title:"タイトルB", size:2621 };
var page_c:Object = { url:"http://example.com/c.html", title:"タイトルC", size:5242 };
var page_x:Object = { url:"http://example.com/x.html", title:"×××××", size:9999 };
var page_y:Object = { url:"http://example.com/y.html", title:"×××××", size:9999 };
var page_z:Object = { url:"http://example.com/z.html", title:"×××××", size:9999 };
 
■辞書を作成する
 
辞書として取り扱うための、Object オブジェクトを 1 つ作成します。
 
辞書用 Object オブジェクトを作成する

// 辞書を作成
var dictionary:Object = new Object();
 
■辞書に既にデータが存在するか調べる
 
指定したプロパティに、すでにデータが存在するか調べます。
 
配列アクセス演算子を使って、調べたいプロパティにアクセスします。
 
結果が、真であればデータが存在します。偽であればデータは存在しません。
 
辞書に既にデータが存在するか調べる

// 辞書を作成
var dictionary:Object = new Object();

// 検索したいアドレス情報
var url:String = "http://example.com/b.html";

// 辞書に既にデータが存在するか調べる
if(dictionary[url]){

	trace("データは存在する");

}else{

	trace("データは存在しない");

}
 
■辞書にデータを登録する
 
任意のプロパティに、データを登録します。
 
配列アクセス演算子を使って、任意のプロパティにデータを格納します。
 
辞書にデータを登録する

// 辞書を作成
var dictionary:Object = new Object();

// 管理したいデータ
var page_b:Object = { url:"http://example.com/b.html", title:"タイトルB", size:2621 };

// 辞書にデータが存在しないか調べる
if(!dictionary[page_b.url]){

	// 辞書に新しいデータを登録する
	dictionary[page_b.url] = page_b;

}
 
■辞書からデータを取得する
 
任意のプロパティから、データを取得します。
 
配列アクセス演算子を使って、任意のプロパティからデータを取得します。
 
null 値が得られる場合、データは存在しません。
 
辞書からデータを取得する

// 辞書を作成
var dictionary:Object = new Object();

// 管理したいデータ
var page_a:Object = { url:"http://example.com/a.html", title:"タイトルA", size:1310 };
var page_b:Object = { url:"http://example.com/b.html", title:"タイトルB", size:2621 };
var page_c:Object = { url:"http://example.com/c.html", title:"タイトルC", size:5242 };

// 辞書にデータを登録する
dictionary[page_a.url] = page_a;
dictionary[page_b.url] = page_b;
dictionary[page_c.url] = page_c;

// 検索したいアドレス情報
var url:String = "http://example.com/a.html";

// 辞書からデータを取得する
var page:Object = dictionary[url];
 
■辞書に登録したデータを削除する
 
任意のプロパティから、データを削除します。
 
delete 文を使って、任意のプロパティを削除します。
 
辞書に登録したデータを削除する

// 辞書を作成
var dictionary:Object = new Object();

// 管理したいデータ
var page_a:Object = { url:"http://example.com/a.html", title:"タイトルA", size:1310 };
var page_b:Object = { url:"http://example.com/b.html", title:"タイトルB", size:2621 };
var page_c:Object = { url:"http://example.com/c.html", title:"タイトルC", size:5242 };

// 辞書にデータを登録する
dictionary[page_a.url] = page_a;
dictionary[page_b.url] = page_b;
dictionary[page_c.url] = page_c;

// 検索したいアドレス情報
var url:String = "http://example.com/a.html";

// 辞書からデータを取得する
var page:Object = dictionary[url];
if(page){
	// 辞書に登録したデータを削除する
	delete dictionary[page.url];
}
 


 

オブジェクトを複製する

 


■オブジェクトを複製する

 
オブジェクトツリーを複製する関数です。
 
null、undefined、Boolean、Number、String、Array、Object 型のデータのみで構成する必要があります。
 
オブジェクトを複製する関数

// ------------------------------------------------------------
// オブジェクトを複製する関数
// ------------------------------------------------------------
function ObjectClone(obj:*):*{
	if(typeof(obj) != "object") return obj;

	var s:Object;
	var o:Object;
	var k:Object;
	var r:Object = new (obj.constructor)();
	var q:Array = new Array();

	q.push({o:r,s:obj});
	while(true){
		k = q.pop();
		if(!k)	break;

		o = k.o;
		s = k.s;
		for(k in s){
			if(typeof(s[k]) == "object"){
				if(s[k]){
					o[k] = new (s[k].constructor)();
					q.push({o:o[k],s:s[k]});
					continue;
				}
			}
			o[k] = s[k];
		}
	}

	return r;
}
 
■使用例
 
オブジェクトツリーを複製する

// ------------------------------------------------------------
// オブジェクトを複製する関数
// ------------------------------------------------------------
function ObjectClone(obj:*):*{
	if(typeof(obj) != "object") return obj;

	var s:Object;
	var o:Object;
	var k:Object;
	var r:Object = new (obj.constructor)();
	var q:Array = new Array();

	q.push({o:r,s:obj});
	while(true){
		k = q.pop();
		if(!k)	break;

		o = k.o;
		s = k.s;
		for(k in s){
			if(typeof(s[k]) == "object"){
				if(s[k]){
					o[k] = new (s[k].constructor)();
					q.push({o:o[k],s:s[k]});
					continue;
				}
			}
			o[k] = s[k];
		}
	}

	return r;
}

// ------------------------------------------------------------
// オブジェクトツリーを作成
// ------------------------------------------------------------
var obj:Object = {
	aaa:{
		count:123,
		name:"テスト1",
		result:false
	},
	bbb:{
		count:456,
		name:"テスト2",
		result:true
	},
	ccc:{
		count:789,
		name:"テスト3",
		param:{
			ary:["a","b","c"],
			name:"テスト4"
		},
		result:true
	}
};

// ------------------------------------------------------------
// オブジェクトを複製
// ------------------------------------------------------------
var clone:Object = ObjectClone(obj);

// 出力テスト
trace(clone);
 


 

参照(リファレンスデータ)について

 


■リファレンス型について

 
すべてのオブジェクトは、リファレンス型に該当します。
 
リファレンス型は、複合的なデータ型です。
 
Array、Object、Function 型などは、すべてリファレンス型です。
 
リファレンスは、参照を意味します。
 
オブジェクトが、どのように参照として動作するか確認してみます。
 

■オブジェクトの参照を確認する

 
1.配列を作成してみる
 
配列を作成して、「変数 ary0 」に格納してみます。
 
配列を作成する

// 配列を作成する
var ary0:Array = ["a","b","c"];
 
 
2.配列を別の変数に代入してみる
 
「変数 ary0 」の中身を、「変数 ary1 」に代入してみます。
 
デバッガでは、以下のように表示されました。
 
「変数 ary0 」の配列が、「変数 ary1 」へとコピーされているように見えます。
 
作成した配列オブジェクトを別の変数に代入する

// 配列を作成する
var ary0:Array = ["a","b","c"];

// 配列を別の変数に代入する
var ary1:Array = ary0;
 
 
3.片方の変数から配列に書き込んでみる
 
次に、「変数 ary1 」から、配列の一部を書き換えてみます。
 
デバッガで確認すると、「変数 ary0 」と「変数 ary1 」の両方の配列が変化しました。
 
内部でどのような処理が行われているのでしょうか。
 
片方の変数から、配列の一部を変更する

// 配列を作成する
var ary0:Array = ["a","b","c"];

// 配列を別の変数に代入する
var ary1:Array = ary0;

// 変数 ary1 から、配列の 0 番地を変更する
ary1[0] = "d";
 
 

■オブジェクトの本体と参照について

 
先ほど、配列オブジェクトを作成して、「変数 ary0 」に格納しました。
 
配列を作成する

// 配列を作成する
var ary0:Array = ["a","b","c"];
 
オブジェクトを作成すると、オブジェクトの本体は、メモリ上のどこかに生成されます。
 
「変数 ary0 」には、「メモリ上のどこかに存在するオブジェクト本体」へアクセスするための、参照データが格納されています。
 
配列オブジェクト本体が、「変数 ary0 」に、直接格納される訳ではありません。
 

■オブジェクトの参照渡しについて

 
先ほど、「変数 ary0 」の中身を「変数 ary1 」に代入しました。
 
このとき、「変数 ary0 」の配列が、「変数 ary1 」へとコピーされた訳ではありません。
 
作成した配列オブジェクトを別の変数に代入する

// 配列を作成する
var ary0:Array = ["a","b","c"];

// 配列を別の変数に代入する
var ary1:Array = ary0;
 
「変数 ary0 」から「変数 ary1 」に渡したのは、「メモリ上のどこかに存在するオブジェクト本体」へアクセスするための、参照データです。
 
これにより、「変数 ary1 」からも、配列オブジェクト本体へアクセスできるようになります。
 
■参照渡しについて
 
リファレンス型のデータを、別の変数に代入する事を、参照渡しと言います。
 
参照渡しを利用すると、複数の変数から、1つのオブジェクト本体を共有できるようになります。
 

■不要になったオブジェクト本体を解放する

 
オブジェクト本体を、直接的に消滅させる命令はありません。
 
delete 文は、オブジェクトを破棄する命令ではありません。( C++ 使いの方は注意)
 
オブジェクトが不要になった場合、オブジェクトを格納している変数を、別の値で上書きします。
 
基本的には、null 値をセットします。
 
配列オブジェクトを解放する

// 配列を作成する
var ary0:Array = ["a","b","c"];

// 変数に null 値をセットする(配列オブジェクト本体にアクセスする手段が失われる)
ary0 = null;
 
オブジェクトの参照データを、別の値で上書きしたので、「メモリ上のどこかに存在するオブジェクト本体」へアクセスする手段が失われる事になります。
 
このとき、ガベージコレクションが、自動的に物理メモリから解放します。
 
■ null 値について
 
null 値とは、リファレンス型のデータが存在しない事を意味します。となります。
 
何らかのリファレンス型のデータが存在する場合は、となります。
 

■ガベージコレクションについて

 
ガベージコレクションは、FlashPlayer から、自動的に、不定期に発生します。
 
ActionScript3.0 では、ガベージコレクションを手動的に動作させる事もできます。
 
詳しくは、こちらで解説しています。
 
ガベージコレクションは、不要になったオブジェクト本体が、物理メモリ上に存在するか調べます。
 
不要なオブジェクト本体があれば、物理メモリから解放します。
 
■不要なオブジェクトを解放するためには?
 
アクセスする手段が失われたオブジェクト本体は、不要なオブジェクトと判別されます。
 
オブジェクトが不要になった場合、参照をすべて断つ必要があります。
 
不要なオブジェクトが格納されている変数があれば、別の値で上書きします。
 
Object オブジェクトを解放する

// オブジェクトを作成する
var obj0:Object = {a:0,b:1,c:2};

// オブジェクトの参照を別の変数に渡す
var obj1:Object = obj0;

// 変数に null 値をセットする(この時点では、obj1 からオブジェクト本体にアクセスできる為、消滅しない)
obj0 = null;

// 変数に null 値をセットする(この時点で、オブジェクト本体にアクセスする手段が失われた為、ガベージコレクションの対象となる)
obj1 = null;
 

■メモリリークについて

 
オブジェクトが不要になった場合、オブジェクトの参照をすべて断つ必要があります。
 
1つでも参照が残っている場合、永遠に解放されずに物理メモリに残り続けます。
 
解放漏れの不備により、ゴミが物理メモリを占有し続ける事を、メモリリークといいます。
 
■エージングテスト
 
一連の処理を、自動的に、繰り返し実行されるようにして、長時間放置します。
 
FlashPlayer がクラッシュしていないか、エラーが発生していないか、物理メモリの使用量が増え続けていないか、異常な動作をしていないかを確認します。
 
長時間の稼動に耐えるほど、安心できます。
 
■表示オブジェクトの解放について
 
表示オブジェクトが、表示リストを通じてステージと繋がっている場合、自動的に解放される事はありません。
 
ステージから、表示リストを巡って、表示オブジェクトへアクセスできる為です。