Flex2 のベータ1からインスタンス変数の宣言に prototype 修飾子を使用することができるようになりました。例えば、以下の例では pProp という変数に prototype 修飾子が定義されています。
public class ProtoSample { public prototype var pProp:int = 10; }
prototype 属性の変数は通常のインスタンス変数と同様に使用することができます。
var p1:ProtoSample = new ProtoSample(); trace(p1.pProp); // 10 が出力される p1.pProp = 20; trace(p1.pProp); // 20 が出力される
一方、クラスオブジェクトの持つ prototype オブジェクトから prototype 属性の変数の値を変更すると、そのクラスのインスタンスが複数存在する場合にはそれらにまとめて変更が反映されます。
var p1:ProtoSample = new ProtoSample(); var p2:ProtoSample = new ProtoSample(); trace(p1.pProp); // 10 が出力される trace(p2.pProp); // 10 が出力される // クラスの prototype オブジェクトから値を変更 ProtoSample.prototype.pProp = 20; trace(p1.pProp); // 20 が出力される trace(p2.pProp); // 20 が出力される
ただし、一旦直接値を変更したインスタンスに対しては変更が反映されません。
var p1:ProtoSample = new ProtoSample(); var p2:ProtoSample = new ProtoSample(); // p2 の pProp の値を直接変更 p2.pProp = 30; // prototype オブジェクトから値を変更 ProtoSample.prototype.pProp = 20; trace(p1.pProp); // 20 が出力される trace(p2.pProp); // 30 が出力される
prototype 修飾子と関数
prototype 修飾子を使用できるのはインスタンス変数のみです。従ってメソッドの宣言に対して prototype 修飾子を使用することはできませんが、(代わりに?) Function 型のインスタンス変数には使うことができます。下の例では、doIt という Function 型のプロパティに prototype 属性を定義しています。
public class ProtoSample { public prototype var doIt:Function = function() { trace("foo"); } }
このように関数を prototype 属性付きで宣言しておくと、インスタンスの振る舞いをまとめて変えることができるようになります。
var p1:ProtoSample = new ProtoSample(); var p2:ProtoSample = new ProtoSample(); p1.doIt(); // foo が出力される p2.doIt(); // foo が出力される // prototype オブジェクト経由で別の関数を設定 ProtoSample.prototype.doIt = bar; p1.doIt(); // bar が出力される p2.doIt(); // bar が出力される // 代入される関数の定義 function bar() { trace("bar"); }
prototype オブジェクトの簡単な補足
prototype オブジェクトを使用すると動的にプロパティを追加定義することができます(注:既存定義の上書き変更はできません)。追加されたプロパティは、prototype 修飾子付きで定義されたプロパティと同じように扱えます。
var p1:ProtoSample = new ProtoSample(); var p2:ProtoSample = new ProtoSample(); ProtoSample.prototype.pProp2 = 100; ProtoSample.prototype.doIt2 = bar; trace(p1.pProp2); // 100 が出力される trace(p2.pProp2); // 100 が出力される p1.doIt2(); // bar が出力される p2.doIt2(); // bar が出力される function bar() { trace("bar"); }
上のコードをコンパイルするには、コンパイルオプションに strict を使用しない、またはプロパティを追加するクラスを dynamic クラスとして宣言する必要があります。いずれにせよコンパイル時の型チェックがあまくなるので、可能な場合はクラス定義時に prototype 修飾子付きのプロパティとして定義しておいたほうが分かりやすいと思います。
コメントする