Como faço para começar a partir de uma instância de uma classe para um objeto de classe no ActionScript 3?

StackOverflow https://stackoverflow.com/questions/203969

Pergunta

Como você recebe uma instância do Class classe ActionScript de uma instância dessa classe?

Em Python, isso seria x.__class__; em Java, x.getClass();.

Estou ciente de que certos hacks terríveis existem para fazer isso , mas eu estou procurando um built-in facilidade de linguagem, ou pelo menos uma rotina de biblioteca construída em algo confiável.

Foi útil?

Solução

Você pode obtê-lo através da propriedade 'Construtor' da classe base objeto. ou seja:.

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

Outras dicas

Você tem algum motivo você não poderia fazer isso?

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]

Eu não sei uma maneira de evitar round-trip através de uma String, mas deve funcionar bem o suficiente.

A (e atualmente resposta mais popular) aceitou tem algumas falhas. A resposta serve para este caso de uso específico, mas os comentários têm expandido a resposta para uma solução geral aparente.

Mas não é uma solução de tipo seguro, em certos casos, e não aborda todos os objetos possíveis. A ideia de que XML não é suportado tem sido abordada muito bem aqui e em outros lugares, mas a idéia de tipo seguro não tem.

A suposição feita é que ele é um objeto de classe criado pelo programador. Aqui estão alguns testes que eu configurado (isto é no modo estrito, mas um teste local). Observe os resultados do teste 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("...");

Com TestClass definido como:

package
{
    public class TestClass
    {
    }
}

Resultado:

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ém de qualquer teste atual, há muito boas razões para uso getDefinitionByName sobre os métodos constructor. O método getDefinitionByName permite:

  • Adobe para desenvolver soluções internas para o (presente e futuro) áreas problemáticas
  • Você não teria que alterar o código para futuros desenvolvimentos Adobe
  • você não tem que desenvolver dois (ou mais) métodos distintos de instanciação dinâmica.

Pode ser mais lento agora, mas no futuro pode haver melhorias do lado da Adobe que abordam a questão da velocidade.

(Por exemplo, ele costumava ser que uint foi muito mais lento no para-loops que int, então um monte de código de conversão foi configurado para usar o int mais rápido. Era uma questão bastante simples de resolver, de modo Adobe fixo -lo, e agora há um monte de código que salta através de alguns aros desnecessários para alcançar uma meta ultrapassada.)

Uma vez que o método getDefinitionByName funciona corretamente em todos os casos, o código deve ser desenvolvido usando esse método, em seguida, trabalhar para obter Adobe para corrigir o problema de velocidade.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top