AS1 OOP: Prototypes
by senocular
Introduction
A prototype is class specific shared value. Each class has
its own prototype object which is used for storing shared
prototype values. These values can be variable values such
as numbers or strings or, and more commonly the case, as
class method functions. Everything contained within this
prototype object is then accessible to each instance of that
class despite the fact that it is not part of that actual
instance itself.
The prototype object for any class resides in the
constructor function for that class. And that’s all the
prototype object is, just a simple object that sits there in
the constructor function waiting to have shared definitions
assigned to it. It’s created automatically by Flash when the
constructor is defined so you won't have to worry about
making it manually. In fact, Flash automatically creates a
prototype object for any function you define assuming its
possible use as a constructor function.
- doesNothingFunction = function(){};
- trace(doesNothingFunction.prototype); // traces
[object Object]
The quickest way to get started with prototypes is using
them on Flash's core objects (classes) such as the Array
object of the MovieClip object. When you define values or
functions in the Array.prototype object, they become
available to all Array instances. This can be very helpful
if you are using something like a common method for a lot or
all of your Array in a Flash movie. Defining it once in the
Array.prototype means all arrays instantly have access to
use that function as though it were assigned directly to it
since everything in the prototype object of Array is shared
among all array instances.
As an example we can use the switchValues function from
before. This function switched the values of the first two
elements of an array. As an array prototype, the function
acts as a method to all arrays and wouldn’t have to be
defined individually for each array that would need to use
it.
- Array.prototype.switchValues = function(){
- var temp = this[0];
- this[0] = this[1];
- this[1] = temp;
- };
- letters = ["A", "B"];
- numbers = [1,2];
- letters.switchValues();
- trace(letters); // traces "B", "A"
- numbers.switchValues();
- trace(numbers); // traces 2, 1
Having been set only once in the Array.prototype, all
arrays are then able to use the function as an array method
– as though it was defined in directly in each.
Here is an example of a MovieClip prototype that will,
when called, cause any movieclip to jump right 100 pixels:
- MovieClip.prototype.jumpRight = function(){
- this._x += 100;
- };
- // used it on clipA in the current timeline
- clipA.jumpRight(); // clipA moves 100 px to the right
In fact, every method you already know as array or
movieclip methods are those that already exist in the Array
and MovieClip prototype objects. This applies to all methods
of predefined Flash objects. Each one of those methods for
each Actionscript object is defined in that class’s
prototype object. The valueOf and toString methods, for
example, are prototype methods.
Just as you would add a prototype to a pre-existing Flash
classes, you can also add them to your own. Take the House
class for example. Before, we added a method directly in the
House class constructor. In doing this, all House instances
created would receive a copy of that function. Keeping that
method in the House prototype object instead of assigning a
copy within the constructor means that all House instances
will still have access to the method, but it will only need
to be physically defined in one place. Then it can be shared
in an optimized non-redundant manner.
- // class definition
- House = function(siding){
- this.floors = 4;
- if (siding != undefined){
- this.siding = siding;
- }else{
- this.siding = "Red";
- }
- };
- // define a method in the House function's prototype
object
- // which is to be shared among all House instances
- House.prototype.outputSiding = function(){
- trace(this.siding);
- };
- // create an instance of the House class
- myHouse = new House();
- myHouse.outputSiding(); // traces "Red"
- // create an blue instance of the House class
- myHouse = new House("Blue");
- myHouse.outputSiding(); // traces "Blue"
With just about every class you make, you'll be wanting
to assign property values in the constructor copying them to
instances, as these are likely to change or be different for
each instance, and have methods shared in the prototype
object of the constructor as they are not unique to each
instance.