Ответ 1
Вы можете получить его через свойство "constructor" базового класса Object. то есть:.
var myClass:Class = Object(myObj).constructor;
Как вы получаете экземпляр класса actionscript Class
из экземпляра этого класса?
В Python это будет x.__class__
; в Java, x.getClass();
.
Я знаю, что некоторые ужасные хаки существуют, но я ищу встроенный языковой инструмент или в как минимум, библиотечная процедура, построенная на чем-то надежном.
Вы можете получить его через свойство "constructor" базового класса Object. то есть:.
var myClass:Class = Object(myObj).constructor;
По какой причине вы не могли этого сделать?
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]
Я не знаю, как избежать кругового отключения через String, но он должен работать достаточно хорошо.
Принятый (и в настоящее время самый популярный ответ) имеет некоторые недостатки. Ответ служит для этого конкретного варианта использования, но комментарии расширили ответ на кажущееся общее решение.
Но в некоторых случаях это не безопасное решение, и оно не относится ко всем возможным объектам. Идея о том, что XML не поддерживается, была достаточно хорошо рассмотрена здесь и в других местах, но идея типа безопасного не имеет.
Сделано предположение, что это объект класса, созданный программистом. Вот несколько тестов, которые я установил (это в строгом режиме, но локальный тест). Обратите внимание на результаты тестирования 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("...");
С TestClass
определяется как:
package
{
public class TestClass
{
}
}
Результаты:
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]
...
Помимо любого текущего тестирования, существует достаточно веская причина использовать getDefinitionByName
для методов constructor
. Метод getDefinitionByName
позволяет:
Теперь это может быть медленнее, но в будущем могут быть улучшения со стороны Adobe, которые будут решать проблему скорости.
(Например, раньше было uint
было намного медленнее для циклов for-loops, чем int
, поэтому было установлено много кода преобразования, чтобы использовать более быстрый int
. Это была довольно простая проблема чтобы решить, поэтому Adobe исправила его, и теперь есть много кода, который перескакивает через несколько ненужных обручей для достижения устаревшей цели.)
Так как метод getDefinitionByName
работает правильно во всех случаях, код должен быть разработан с использованием этого метода, а затем работать, чтобы заставить Adobe исправить скорость.