AS3 Prototypes - are they just static variables? - actionscript-3

A reference to the prototype object of a class or function object. The
prototype property is automatically created and attached to any class
or function object that you create. This property is static in that it
is specific to the class or function that you create. For example, if
you create a class, the value of the prototype property is shared by
all instances of the class and is accessible only as a class property.
Instances of your class cannot directly access the prototype property.
A class’s prototype object is a special instance of that class that
provides a mechanism for sharing state across all instances of a
class. At run time, when a property is not found on a class instance,
the delegate, which is the class prototype object, is checked for that
property. If the prototype object does not contain the property, the
process continues with the prototype object’s delegate checking in
consecutively higher levels in the hierarchy until Flash Player or the
Adobe Integrated Runtime finds the property.
Note: In ActionScript 3.0, prototype inheritance is not the primary
mechanism for inheritance. Class inheritance, which drives the
inheritance of fixed properties in class definitions, is the primary
inheritance mechanism in ActionScript 3.0.
So, from this I get the impression that prototypes are just static variables.. am I right?

Not exactly, a function implemented as a prototype is still executed as instance method. In a static function you don't have access to this.
Also it doesn't mean setting a prototype value to something is setting the value for every instance. It's only the fallback value, if an object of that class isn't setting it explicitly.
var o1:Object= {};
var o2:Object= {};
Object.prototype.foo = "foo";
o1.foo = "bar"
trace(o1.foo) // bar
trace(o2.foo) // foo

Related

Can the Proxy class be used in AS3 on existing classes?

The AS3 Proxy class extends Object and exposes methods that you can override to handle the addition/removal and getting/setting of properties on the object in a universal fashion.
It appears that existing objects such as MovieClip, Sprite, etc. do not inherit from the Proxy class, so it would seem to preclude the possibility of adding such functionality to existing display object classes.
I've created a layout framework with a base display object class called GUIControl that inherits from MovieClip, and I was hoping to add data-binding functionality to it by overriding the Proxy class's setProperty method, so I could handle property assignments with a single handler to make all properties function as binding sources by default.
Is there some way to utilize the Proxy class's functionality on existing classes, or am I stuck building classes from scratch based on Proxy?
You may create a wrapper class for MovieClip and set property on the wrapper. You should override other functions in Proxy and call the relative functions on MovieClip.
Here is an example
import flash.display.MovieClip;
import flash.utils.Proxy;
import flash.utils.flash_proxy;
public class MovieClipWrapper extends Proxy
{
public function MovieClipWrapper(target:MovieClip)
{
super();
_target = target;
}
private var _target:MovieClip;
override flash_proxy function setProperty(name:*, value:*):void
{
//set data on target movieClip, or call the notify functions
}
}
No, it cannot be used on existing classes. The worst part is that rules out using Proxy on any display list classes. There is no way to alter a property on a display list class and have the Proxy class intercept and handle the setting or getting of such a property value. Proxy is useful only as a base class for new classes (ideally dynamic classes), where you want to intercept and run logic when properties are set/retreived/removed.
Futhermore, Proxy is useless for trying to wrap something like the Dictionary class, since Proxy's interface methods rely on QName and String-type keys exclusively, which makes it impossible to enumerate over, get, or set Dictionary values that use object instances as keys... something Dictionary supports unlike associative arrays or normal Objects.

Actionscript-3 prototype inheritance

Basically, I want to modify the constructor of the Object
class. Since every class extends Object, I hope whenever any
object of any class is instantiated, the modified function will
be called.
So I did this :
Object.prototype.constructor = function (){
trace("it was called;");
};
and put a breakpoint on the trace statement.
But it didn't stop there.
The trace statement did not get executed also.
Any solutions/suggestions?
In which context are you coding?
If you're using the Flex Compiler MXMLC (default, if you're in FlashBuilder), than you could add the compiler option -es. This should make AS3 feel more like AS2 and JS and support the prototype chain inheritance.
-compiler.es alias -es
"use the ECMAScript edition 3 prototype based object model to allow dynamic overriding of prototype properties. In the prototype based object model built-in functions are implemented as dynamic properties of prototype objects. (advanced)"
I don't know, if this plays well with all the extensions Adobe added to the ECMA Script standard, like packages, namespaces and classes. But you could give it a try.
I don't think it's possible in AS-3, but it was in AS-2.

Besides creating an instance, how to tell if ClassA descends from ClassB in ActionScript?

I need to determine if one class descends (directly or indirectly) from another.
I can do
var testInstance : Object = new ClassA();
if (testInstance is ClassB)
...
but I hate creating an instance just to test ancestry. I hoped that if (ClassA is ClassB) would work, but it does not seem to.
AS help states
isPrototypeOf(theClass:Object):Boolean
Indicates whether an instance of the Object class is in the prototype chain of the object specified as the
parameter.
I don't actually understand ActionScript prototypes (I think it might drive me insane), but I hope that Class objects have some way of tapping into their inheritance information.
Thanks
Prototypes are instances, either of the class (for class inheritance) or the parent class (for prototype inheritance). Try:
Object.prototype.extends=function (theClass:Object):boolean {
return this.prototype instanceof theClass;
}
ClassA.extends(ClassB);
ActionScript 3 shoehorns prototype inheritance into class based inheritance. You don't use prototypes much anymore in Actionscript, but it's not a complex concept and has its uses, so you'd do well to study it. Read "History of ActionScript OOP support" and "The prototype object" from "Advanced topics"

Is it possible to intercept attribute getting/setting in ActionScript 3?

When developing in ActionScript 3, I often find myself looking for a way to achieve something similar to what is offered by python's __getattr__ / __setattr__ magic methods i.e. to be able to intercept attribute lookup on an instance, and do something custom.
Is there some acceptable way to achieve this in ActionScript 3? In AS3 attribute lookup behaves a little differently for normal (sealed) and dynamic classes -- ideally this would work in the same way for both cases. In python this works beautifully for all kinds of objects (of course!) even for subclasses of dict itself!
Look a the flash.utils.Proxy object.
The Proxy class lets you override the
default behavior of ActionScript
operations (such as retrieving and
modifying properties) on an object.
In AS3 you can code explicit variables accessors.
Example Class1:
private var __myvar:String;
public function get myvar():String { return __myvar; }
public function set myvar(value:String):void { __myvar = value; }
Now as you create an instance of Class1 you can access __myvar through the accessor functions.
if you want to set bindable that var you have to put the [Bindable] keyword upon one of its accessors.
Further, you can also implement the getter or the setter only, so your var will be read or write only.
I hope it helps.

extending a class and implementing an interface

I am creating objects for a game, they are all sprites. but I also want them to implement an interface. Is it possible to do both ? If not, how can i have an object have the capabilities of a sprite and also have it implement an interface. I am wanting to create another class that checks all my objects to see what datatype they are and evaluate them accordingly
It is possible for all ActionScript objects to both implement an interface and extend a class. Here's an example:
public class RedZoid extends Sprite implements IColoredZoid
Furthermore, the is keyword works with interface implementations:
var z1:RedZoid = new RedZoid();
if (z1 is IColoredZoid) {
// This branch will be hit, since the interface is implemented
}