如何从ActionScript 3中的类实例获取Class对象?

时间:2022-04-05 23:17:55

How do you get an instance of the actionscript class Class from an instance of that class?

如何从该类的实例中获取actionscript类Class的实例?

In Python, this would be x.__class__; in Java, x.getClass();.

在Python中,这将是x .__ class__;在Java中,x.getClass();.

I'm aware that certain terrible hacks exist to do this, but I'm looking for a built-in language facility, or at least a library routine built on something reliable.

我知道有一些可怕的黑客可以做到这一点,但我正在寻找一个内置的语言设施,或者至少是建立在可靠的基础上的库例程。

3 个解决方案

#1


69  

You can get it through the 'constructor' property of the base Object class. i.e.:

您可以通过基础Object类的“constructor”属性获取它。即:

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

#2


14  

Any reason you couldn't do this?

你有什么理由不能这样做吗?

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]

I don't know a way to avoid round-tripping through a String, but it should work well enough.

我不知道如何避免通过String进行往返,但它应该运行得很好。

#3


14  

The accepted (and currently most popular answer) has some flaws. The answer serves for this specific use case, but the comments have expanded the answer to a seeming general solution.

被接受的(当前最流行的答案)有一些缺陷。答案适用于此特定用例,但评论已将答案扩展为看似一般的解决方案。

But it is not a type-safe solution in certain cases, and it doesn't address all possible objects. The idea that XML is not supported has been addressed well enough here and elsewhere, but the type-safe idea has not.

但在某些情况下,它不是类型安全的解决方案,并不能解决所有可能的对象。 XML不受支持的想法已经在这里和其他地方得到了很好的解决,但类型安全的想法却没有。

The assumption made is that it is an class object created by the programmer. Here are some tests that I set up (this is in strict mode, but a local test). Note the int test results:

假设它是由程序员创建的类对象。以下是我设置的一些测试(这是严格模式,但是本地测试)。注意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("...");

With TestClass defined as:

使用TestClass定义为:

package
{
    public class TestClass
    {
    }
}

Results:

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

Beyond any current testing, there is fairly good reason to use getDefinitionByName over the constructor methods. The getDefinitionByName method allows :

除了当前的测试之外,还有相当好的理由在构造函数方法上使用getDefinitionByName。 getDefinitionByName方法允许:

  • Adobe to develop internal solutions for the (current and future) problematic areas
  • Adobe为(当前和未来)有问题的领域开发内部解决方案

  • you would not have to change your code for future Adobe developments
  • 您不必为将来的Adobe开发更改代码

  • you do not have to develop two (or more) separate methods of dynamic instantiation.
  • 您不必开发两个(或更多)单独的动态实例化方法。

It may be slower now, but in the future there may be improvements from Adobe's side that would address the speed issue.

它现在可能会变慢,但在未来可能会有Adobe的改进来解决速度问题。

(For example, it used to be that uint was far slower in for-loops than int, so a lot of conversion code was set up to use the faster int. It was a fairly simple issue to solve, so Adobe fixed it, and now there is a lot of code that jumps through some unnecessary hoops to achieve an outdated goal.)

(例如,过去因为uint在for循环中比int慢得多,所以设置了很多转换代码以使用更快的int。这是一个相当简单的问题需要解决,所以Adobe修复了它,现在有很多代码会跳过一些不必要的箍来实现过时的目标。)

Since the getDefinitionByName method works correctly in all cases, code should be developed using that method, and then work to get Adobe to fix the speed issue.

由于getDefinitionByName方法在所有情况下都能正常工作,因此应使用该方法开发代码,然后使用Adobe来解决速度问题。

#1


69  

You can get it through the 'constructor' property of the base Object class. i.e.:

您可以通过基础Object类的“constructor”属性获取它。即:

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

#2


14  

Any reason you couldn't do this?

你有什么理由不能这样做吗?

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]

I don't know a way to avoid round-tripping through a String, but it should work well enough.

我不知道如何避免通过String进行往返,但它应该运行得很好。

#3


14  

The accepted (and currently most popular answer) has some flaws. The answer serves for this specific use case, but the comments have expanded the answer to a seeming general solution.

被接受的(当前最流行的答案)有一些缺陷。答案适用于此特定用例,但评论已将答案扩展为看似一般的解决方案。

But it is not a type-safe solution in certain cases, and it doesn't address all possible objects. The idea that XML is not supported has been addressed well enough here and elsewhere, but the type-safe idea has not.

但在某些情况下,它不是类型安全的解决方案,并不能解决所有可能的对象。 XML不受支持的想法已经在这里和其他地方得到了很好的解决,但类型安全的想法却没有。

The assumption made is that it is an class object created by the programmer. Here are some tests that I set up (this is in strict mode, but a local test). Note the int test results:

假设它是由程序员创建的类对象。以下是我设置的一些测试(这是严格模式,但是本地测试)。注意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("...");

With TestClass defined as:

使用TestClass定义为:

package
{
    public class TestClass
    {
    }
}

Results:

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

Beyond any current testing, there is fairly good reason to use getDefinitionByName over the constructor methods. The getDefinitionByName method allows :

除了当前的测试之外,还有相当好的理由在构造函数方法上使用getDefinitionByName。 getDefinitionByName方法允许:

  • Adobe to develop internal solutions for the (current and future) problematic areas
  • Adobe为(当前和未来)有问题的领域开发内部解决方案

  • you would not have to change your code for future Adobe developments
  • 您不必为将来的Adobe开发更改代码

  • you do not have to develop two (or more) separate methods of dynamic instantiation.
  • 您不必开发两个(或更多)单独的动态实例化方法。

It may be slower now, but in the future there may be improvements from Adobe's side that would address the speed issue.

它现在可能会变慢,但在未来可能会有Adobe的改进来解决速度问题。

(For example, it used to be that uint was far slower in for-loops than int, so a lot of conversion code was set up to use the faster int. It was a fairly simple issue to solve, so Adobe fixed it, and now there is a lot of code that jumps through some unnecessary hoops to achieve an outdated goal.)

(例如,过去因为uint在for循环中比int慢得多,所以设置了很多转换代码以使用更快的int。这是一个相当简单的问题需要解决,所以Adobe修复了它,现在有很多代码会跳过一些不必要的箍来实现过时的目标。)

Since the getDefinitionByName method works correctly in all cases, code should be developed using that method, and then work to get Adobe to fix the speed issue.

由于getDefinitionByName方法在所有情况下都能正常工作,因此应使用该方法开发代码,然后使用Adobe来解决速度问题。