そのクラスのインスタンスからactionscript クラスのインスタンスを取得するにはどうすればよいですClass
か?
Python では、これはx.__class__
; Javaでは、x.getClass();
.
これを行うための恐ろしいハックが存在することは知っていますが、組み込みの言語機能、または少なくとも信頼できるものに基づいて構築されたライブラリ ルーチンを探しています。
そのクラスのインスタンスからactionscript クラスのインスタンスを取得するにはどうすればよいですClass
か?
Python では、これはx.__class__
; Javaでは、x.getClass();
.
これを行うための恐ろしいハックが存在することは知っていますが、組み込みの言語機能、または少なくとも信頼できるものに基づいて構築されたライブラリ ルーチンを探しています。
基本 Object クラスの「constructor」プロパティを介して取得できます。すなわち:
var myClass:Class = Object(myObj).constructor;
受け入れられている(そして現在最も人気のある回答)にはいくつかの欠陥があります。答えはこの特定のユースケースに役立ちますが、コメントは答えを一般的な解決策に拡張しました。
ただし、場合によってはタイプ セーフなソリューションではなく、考えられるすべてのオブジェクトに対応しているわけではありません。XML がサポートされていないという考えは、ここや他の場所で十分に対処されていますが、タイプ セーフな考えはそうではありません。
これは、プログラマによって作成されたクラス オブジェクトであると想定されています。ここに私が設定したいくつかのテストがあります (これは厳密モードですが、ローカル テストです)。int
テスト結果に注意してください。
var sprite:Sprite = new Sprite();
var xml:XML = new XML();
var testInt:int = 2;
var testClass:TestClass = new TestClass();
var testAnon:Object = {};
trace("classname 1 = " + getQualifiedClassName(sprite));
trace("myclass 1 = " + getDefinitionByName(getQualifiedClassName(sprite)));
trace("constructor a 1 = " + Object(sprite).constructor);
trace("constructor a 1 = " + (Object(sprite).constructor as Class));
trace("constructor b 1 = " + sprite["constructor"]);
trace("constructor b 1 = " + (sprite["constructor"] as Class));
trace("...");
trace("classname 2 = " + getQualifiedClassName(xml));
trace("myclass 2 = " + getDefinitionByName(getQualifiedClassName(xml)));
trace("constructor a 2 = " + Object(xml).constructor);
trace("constructor a 2 = " + (Object(xml).constructor as Class));
trace("constructor b 2 = " + xml["constructor"]);
trace("constructor b 2 = " + (xml["constructor"] as Class));
trace("...");
trace("classname 3 = " + getQualifiedClassName(testInt));
trace("myclass 3 = " + getDefinitionByName(getQualifiedClassName(testInt)));
trace("constructor a 3 = " + Object(testInt).constructor);
trace("constructor a 3 = " + (Object(testInt).constructor as Class));
trace("constructor b 3 = " + testInt["constructor"]);
trace("constructor b 3 = " + (testInt["constructor"] as Class));
trace("...");
trace("classname 4 = " + getQualifiedClassName(testClass));
trace("myclass 4 = " + getDefinitionByName(getQualifiedClassName(testClass)));
trace("constructor a 4 = " + Object(testClass).constructor);
trace("constructor a 4 = " + (Object(testClass).constructor as Class));
trace("constructor b 4 = " + testClass["constructor"]);
trace("constructor b 4 = " + (testClass["constructor"] as Class));
trace("...");
trace("classname 5 = " + getQualifiedClassName(testAnon));
trace("myclass 5 = " + getDefinitionByName(getQualifiedClassName(testAnon)));
trace("constructor a 5 = " + Object(testAnon).constructor);
trace("constructor a 5 = " + (Object(testAnon).constructor as Class));
trace("constructor b 5 = " + testAnon["constructor"]);
trace("constructor b 5 = " + (testAnon["constructor"] as Class));
trace("...");
次のようにTestClass
定義されています。
package
{
public class TestClass
{
}
}
結果:
classname 1 = flash.display::Sprite
myclass 1 = [class Sprite]
constructor a 1 = [class Sprite]
constructor a 1 = [class Sprite]
constructor b 1 = [class Sprite]
constructor b 1 = [class Sprite]
...
classname 2 = XML
myclass 2 = [class XML]
constructor a 2 =
constructor a 2 = null
constructor b 2 =
constructor b 2 = null
...
classname 3 = int
myclass 3 = [class int]
constructor a 3 = [class Number]
constructor a 3 = [class Number]
constructor b 3 = [class Number]
constructor b 3 = [class Number]
...
classname 4 = src::TestClass
myclass 4 = [class TestClass]
constructor a 4 = [class TestClass]
constructor a 4 = [class TestClass]
constructor b 4 = [class TestClass]
constructor b 4 = [class TestClass]
...
classname 5 = Object
myclass 5 = [class Object]
constructor a 5 = [class Object]
constructor a 5 = [class Object]
constructor b 5 = [class Object]
constructor b 5 = [class Object]
...
getDefinitionByName
現在のテストを超えて、constructor
メソッドを使用するかなりの理由があります。このgetDefinitionByName
メソッドにより、次のことが可能になります。
現在は遅くなる可能性がありますが、将来的にはアドビ側から速度の問題に対処する改善が行われる可能性があります。
(たとえば、以前uint
は は for ループで よりもはるかに遅かったためint
、より高速な を使用するように多くの変換コードが設定されていましたint
。解決するのはかなり簡単な問題だったので、アドビはそれを修正し、現在は時代遅れの目標を達成するために、いくつかの不要なフープをジャンプする多くのコード。)
このgetDefinitionByName
方法はすべての場合に正しく機能するため、その方法を使用してコードを開発し、アドビに速度の問題を修正してもらうように依頼する必要があります。
これができなかった理由はありますか?
var s:Sprite = new flash.display.Sprite();
var className:String = flash.utils.getQualifiedClassName( s );
var myClass:Class = flash.utils.getDefinitionByName( className ) as Class;
trace(className ); // flash.display::Sprite
trace(myClass); // [class Sprite]
var s2 = new myClass();
trace(s2); // [object Sprite]
String のラウンドトリップを回避する方法はわかりませんが、十分に機能するはずです。