Pregunta

¿Cómo se obtiene una instancia de la clase actionscript Class de una instancia de esa clase?

En Python, esto sería x .__ class__ ; en Java, x.getClass (); .

Soy consciente de que existen ciertos ataques terribles para hacer esto , pero estoy buscando una instalación de lenguaje integrada, o al menos una rutina de biblioteca basada en algo confiable.

¿Fue útil?

Solución

Puede obtenerlo a través de la propiedad 'constructor' de la clase de objeto base. es decir:

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

Otros consejos

¿Alguna razón por la que no pudiste hacer esto?

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]

No conozco una forma de evitar los viajes de ida y vuelta a través de una cadena, pero debería funcionar lo suficientemente bien.

La respuesta aceptada (y actualmente la más popular) tiene algunos defectos. La respuesta sirve para este caso de uso específico, pero los comentarios han ampliado la respuesta a una solución general aparente.

Pero no es una solución de tipo seguro en ciertos casos, y no aborda todos los objetos posibles. La idea de que XML no es compatible se ha abordado suficientemente bien aquí y en otros lugares, pero la idea de tipo seguro no.

La suposición hecha es que es un objeto de clase creado por el programador. Aquí hay algunas pruebas que configuré (esto está en modo estricto, pero una prueba local). Tenga en cuenta los resultados de la prueba 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 definido como:

package
{
    public class TestClass
    {
    }
}

Resultados:

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

Más allá de cualquier prueba actual, hay una razón bastante buena para usar getDefinitionByName sobre los métodos constructor . El método getDefinitionByName permite:

  • Adobe desarrollará soluciones internas para las áreas problemáticas (actuales y futuras)
  • no tendría que cambiar su código para futuros desarrollos de Adobe
  • no tiene que desarrollar dos (o más) métodos separados de instanciación dinámica.

Puede ser más lento ahora, pero en el futuro puede haber mejoras por parte de Adobe que aborden el problema de la velocidad.

(Por ejemplo, solía ser que uint era mucho más lento en bucles for que int , por lo que se configuró una gran cantidad de código de conversión para utilizarlo más rápido int . Era un problema bastante simple de resolver, por lo que Adobe lo solucionó, y ahora hay un montón de código que salta a través de algunos aros innecesarios para lograr un objetivo desactualizado).

Dado que el método getDefinitionByName funciona correctamente en todos los casos, el código debe desarrollarse utilizando ese método y luego trabajar para que Adobe solucione el problema de velocidad.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top