Domanda

Come si ottiene un'istanza della classe actionscript Class da un'istanza di quella classe?

In Python, questo sarebbe x .__ class__ ; in Java, x.getClass (); .

Sono consapevole che esistono alcuni terribili hack per farlo , ma sto cercando una struttura linguistica integrata, o almeno una routine di libreria basata su qualcosa di affidabile.

È stato utile?

Soluzione

Puoi ottenerlo tramite la proprietà 'constructor' della classe Object di base. cioè:.

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

Altri suggerimenti

Qualche motivo per cui non puoi farlo?

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]

Non conosco un modo per evitare il round trip in una stringa, ma dovrebbe funzionare abbastanza bene.

La risposta accettata (e attualmente la risposta più popolare) presenta alcuni difetti. La risposta serve per questo caso d'uso specifico, ma i commenti hanno ampliato la risposta a una soluzione apparentemente generale.

Ma in alcuni casi non è una soluzione sicura per i tipi e non risolve tutti i possibili oggetti. L'idea che XML non sia supportato è stata affrontata abbastanza bene qui e altrove, ma non è stata pensata l'idea di tipo sicuro.

Il presupposto è che si tratta di un oggetto di classe creato dal programmatore. Ecco alcuni test che ho impostato (questo è in modalità rigorosa, ma un test locale). Nota i risultati del test 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("...");

Con TestClass definito come:

package
{
    public class TestClass
    {
    }
}

Risultati:

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

Al di là di qualsiasi test corrente, ci sono buone ragioni per usare getDefinitionByName sui metodi costruttore . Il metodo getDefinitionByName consente:

  • Adobe sviluppa soluzioni interne per le aree problematiche (attuali e future)
  • non dovresti cambiare il codice per futuri sviluppi di Adobe
  • non è necessario sviluppare due (o più) metodi separati di istanza dinamica.

Ora potrebbe essere più lento, ma in futuro potrebbero esserci miglioramenti da parte di Adobe che potrebbero risolvere il problema della velocità.

(Ad esempio, in passato uint era molto più lento nei for-loop rispetto a int , quindi è stato impostato un sacco di codice di conversione per utilizzare il più veloce int . È stato un problema abbastanza semplice da risolvere, quindi Adobe lo ha risolto e ora c'è un sacco di codice che salta attraverso alcuni cerchi inutili per raggiungere un obiettivo obsoleto.)

Poiché il metodo getDefinitionByName funziona correttamente in tutti i casi, il codice deve essere sviluppato utilizzando tale metodo, quindi lavorare per far sì che Adobe risolva il problema di velocità.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top