flex für - Wie bekomme ich von einer Instanz einer Klasse in ActionScript 3 ein Klassenobjekt?





länge meta (4)


Kannst du das nicht tun?

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]

Ich kenne keine Möglichkeit, Rundstreichen durch einen String zu vermeiden, aber es sollte gut genug funktionieren.

Wie erhalten Sie eine Instanz der ActionScript Class von einer Instanz dieser Klasse?

In Python wäre dies x.__class__ ; in Java, x.getClass(); .

Ich bin mir bewusst, dass dafür einige schreckliche Hacks existieren, aber ich bin auf der Suche nach einer integrierten Spracheinrichtung oder zumindest einer Bibliotheksroutine, die auf etwas Zuverlässigem aufgebaut ist.




Die angenommene (und derzeit populärste Antwort) hat einige Fehler. Die Antwort dient diesem speziellen Anwendungsfall, aber die Kommentare haben die Antwort auf eine scheinbare allgemeine Lösung erweitert.

In bestimmten Fällen ist es jedoch keine typsichere Lösung, und es werden nicht alle möglichen Objekte angesprochen. Die Idee, dass XML nicht unterstützt wird, wurde hier und anderswo gut angesprochen, aber die typensichere Idee nicht.

Die Annahme ist, dass es sich um ein Klassenobjekt handelt, das vom Programmierer erstellt wurde. Hier sind einige Tests, die ich eingerichtet habe (dies ist im strikten Modus, aber ein lokaler Test). Beachten Sie die int Testergebnisse:

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("...");

Mit TestClass definiert als:

package
{
    public class TestClass
    {
    }
}

Ergebnisse:

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]
...

Jenseits aller aktuellen Tests gibt es einen guten Grund, getDefinitionByName über die constructor verwenden. Die getDefinitionByName Methode ermöglicht:

  • Adobe entwickelt interne Lösungen für die (aktuellen und zukünftigen) Problembereiche
  • Sie müssten Ihren Code für zukünftige Adobe-Entwicklungen nicht ändern
  • Sie müssen nicht zwei (oder mehr) separate Methoden der dynamischen Instanziierung entwickeln.

Es könnte jetzt langsamer sein, aber in Zukunft könnte es Verbesserungen von Seiten von Adobe geben, die das Geschwindigkeitsproblem lösen würden.

(Zum Beispiel war es früher so, dass uint in for-loops viel langsamer war als int , daher wurde viel Conversion-Code eingerichtet, um den schnelleren int . Es war ein ziemlich einfaches Problem, also behob Adobe es und jetzt gibt es eine Menge Code, der durch einige unnötige Ringe springt, um ein veraltetes Ziel zu erreichen.)

Da die getDefinitionByName Methode in allen Fällen korrekt funktioniert, sollte Code mit dieser Methode entwickelt werden, und anschließend Adobe dazu veranlassen, das Geschwindigkeitsproblem zu beheben.




Sie können es über die Eigenschaft 'constructor' der Basisobjektklasse abrufen. zB:

var myClass:Class = Object(myObj).constructor;



Beim Festlegen eines null in ActionScript wird die Zeichenfolge "NULL" . Meine Vermutung ist, dass jemand entschieden hat, dass es daher eine gute Idee ist, die Zeichenfolge "NULL" als null zu dekodieren, was den Bruch verursacht, den Sie hier sehen - wahrscheinlich, weil sie in null und wann Zeichenfolgen in der Datenbank abgerufen wurden Das wollten sie nicht (also sollte man auch auf diese Art von Fehlern achten).







flex flash actionscript-3 actionscript