Avg. Rating 4.2

Problem

I need to get definition of instance to clone object or specify action for it. This can be very helpful when use loaded SWFs.

Solution

All objects, even top level, has constructor property, that contain definition of Class object.

Detailed explanation

Object.constructor property can be used to get object definition:


var objectDefinition:Class = Object( new Sprite()).constructor;
      trace (objectDefinition); // [class Sprite]
var numberDefinition:Class = Object(4).constructor;
      trace (numberDefinition); // [class Number]
var arrayDefinition:Class = Object([]).constructor;
      trace (arrayDefinition); // [class Array]


After you get a definition, you can instantiate it:


var displayObjectDefinition:Class = Object( new Sprite()).constructor;
var newSprite:Sprite = new displayObjectDefinition();


Or, you can use it to specify action by object type(object definition):


switch (Object(displayObject).constructor){
      case MovieClip:
            // actions for MovieClip
      break ;
      case Shape:
            // actions for Shape
      break ;
      case Sprite:
            // actions for Sprite
      break ;
      case SimpleButton:
            // actions for SimpleButton
      break ;
}


Or, create such collection class:


package {
  import flash.utils.Dictionary;
  /**
  * Save single instances by its types
  * @public
  */
  public class Instances extends Object{
  static private var _instances:Dictionary = new Dictionary();
  /**
   * Saves instance by its type
   * @public
   * @throw Error if instance of this type is already registered
   * @param instance Instance to save
   * @return void
   */
  static public function register(instance:Object): void {
   var definition:Class = Object(instance).constructor;
   if (definition in _instances) throw new Error( 'Instance of ' +String(definition)+ ' already registered.' );
   _instances[definition] = instance;
  }
  /**
   * Removes saved instance by another instance with same type or by class definition
   * @public
   * @param instance Instance to save
   * @return Boolean Method call success
   */
  static public function remove(object:Object):Boolean{
   if (!(object is Class)) object = Object(object).constructor;
   return delete _instances[object];
  }
  /**
   * Get saved instance by definition
   * @public
   * @throw Error if instance of this type is not exists
   * @param definition Definition of saved instance
   * @return * Saved instance
   */
  static public function getInstance(definition:Class):*{
   if (!(definition in _instances)) throw new Error( 'Instance of ' +String(definition)+ ' not found.' );
   return _instances[definition];
  }
 }
}


And use it to collect instances by its type:


var sprite:Sprite = new Sprite();
Instances.register(sprite);
      trace (Instances.getInstance(Sprite)); // [object Sprite]
       trace (sprite === Instances.getInstance(Sprite)); // true


Almost in all cases Object.constructor property returns Class object, but there are exceptions:


package {
      import flash.display.Sprite;
      import flash.utils.getQualifiedClassName;
 
      public class Test extends Sprite{
            public function Test(): void {
                  super ();
                  var instance:Object = new myDefintion( "some string" );
                  trace (getQualifiedClassName(instance.constructor));
                  trace (instance.constructor);
                  trace (instance);
 
            }
            protected var myDefintion:Function = function (value:String): void {
                  this .string = value;
                  this .toString = function ():String{
                        return '[Object("' + this .string+ '")]' ;
                  }
            }
      }
}
/* OUTPUT
Function-2
function Function() {}
[Object("some string")]
*/
 
 

Instances.zip
[Instances class from example]
Report abuse

Related recipes