Como faço para começar a partir de uma instância de uma classe para um objeto de classe no ActionScript 3?
-
03-07-2019 - |
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.
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.