【问题标题】:How do I get from an instance of a class to a Class object in ActionScript 3?如何在 ActionScript 3 中从一个类的实例到一个 Class 对象?
【发布时间】:2010-09-17 06:24:10
【问题描述】:

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

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

我知道 certain terrible hacks 的存在可以做到这一点,但我正在寻找一种内置的语言工具,或者至少是一个建立在可靠的东西上的库例程。

【问题讨论】:

    标签: apache-flex flash actionscript-3 actionscript


    【解决方案1】:

    公认的(也是目前最流行的答案)有一些缺陷。答案适用于这个特定的用例,但 cmets 已将答案扩展为看似通用的解决方案。

    但在某些情况下它不是类型安全的解决方案,并且它不能处理所有可能的对象。不支持 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 为(当前和未来)有问题的领域开发内部解决方案
    • 您不必为将来的 Adob​​e 开发更改代码
    • 您不必开发两种(或更多)独立的动态实例化方法。

    现在可能会变慢,但将来 Adob​​e 方面可能会进行改进以解决速度问题。

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 据我所知,这是我自己的瑰宝,尽管 Object 类的 Adob​​e 文档提到了构造函数属性及其含义。我从未见过它在其他任何地方都以这种方式使用过。
      • 在这里进行更多讨论:joshblog.net/2009/05/11/… 一种轻微的替代方法是: var classRef:Class = myObj["constructor"] as Class;这也绕过了严格的编译器检查。不确定哪个表现更好。迈克室
      • 这不适用于代理子类的对象,例如 XML。看到这个答案 - stackoverflow.com/questions/468925/…
      • 那真是太好了。巧妙地避免了我在主舞台上引用课程时遇到的问题。非常感谢
      【解决方案3】:

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

      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]
      

      我不知道如何避免通过字符串往返,但它应该可以很好地工作。

      【讨论】:

      • 这可行,但 getQualifiedClassName 和 getDefinitionByName 的性能很差。迈克室
      猜你喜欢
      • 1970-01-01
      • 2011-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多