ActionScript 1.0 has no class keyword. Every object is a set of named
properties that can be added and removed at any time, and objects share behaviour by
linking to a prototype object, as in JavaScript. A “class” is a constructor function and
the methods put on its prototype. The .as files of this time that were not
plain libraries usually held one such constructor.
Objects
var player = new Object();
player.name = "Ann";
player["score"] = 0;
var point = {x: 10, y: 20}; // an object literal
delete point.y;
for (var p in player) trace(p + ": " + player[p]);
In Flash 5 the Object constructor takes no argument. Arrays, dates,
sounds, movie clips and the rest are objects too, and take extra properties the same
way: ball_mc.speed = 4 stores a value on a movie clip.
Constructors and prototypes
A constructor is an ordinary function called with new. The new object
is this inside it, and the function’s prototype object is
linked to it as its __proto__. Reading a property the object does not
have follows the __proto__ links until it is found, so methods put on
the prototype are shared by every object the constructor makes.
// Ball.as
function Ball(x, y, radius) {
this.x = x;
this.y = y;
this.radius = radius;
}
Ball.prototype.speed = 2;
Ball.prototype.move = function (dx, dy) {
this.x += dx * this.speed;
this.y += dy * this.speed;
};
Ball.prototype.toString = function () {
return "[Ball " + this.x + "," + this.y + "]";
};
var b = new Ball(0, 0, 5);
b.move(1, 0);
trace(b); // [Ball 2,0]
trace(b.__proto__ == Ball.prototype); // true
| Property | Is | Player |
|---|---|---|
F.prototype | The object shared by everything new F() makes. | 5 |
obj.__proto__ | The prototype an object inherits from. It can be read and set. | 5 |
obj.constructor | The function that made the object. | 5 |
Inheritance
A “subclass” is made by linking its prototype to the superclass’s. Two idioms were used:
function Shape(name) { this.name = name; }
Shape.prototype.describe = function () { return this.name; };
// Flash 5: the prototype is an instance of the superclass
function Circle(r) { this.name = "circle"; this.r = r; }
Circle.prototype = new Shape();
// Or: link the prototypes directly
function Triangle() { this.name = "triangle"; }
Triangle.prototype.__proto__ = Shape.prototype;
// Flash MX: call the superclass with super
function Square(side) {
super("square");
this.side = side;
}
Square.prototype = new Shape();
Square.prototype.describe = function () {
return super.describe() + " of side " + this.side;
};
trace(new Square(3).describe()); // square of side 3
trace(new Square(3) instanceof Shape); // true
super, which needs Flash
Player 6.Making the prototype with new runs the superclass constructor once
while setting up, with no arguments, and leaves any properties it sets on the shared
prototype. Assigning __proto__ avoids that, but the subclass constructor
then has to set everything itself. super(…) in a constructor runs the
superclass constructor on this, and super.method() runs the
superclass’s version of a method; both arrived with Flash MX, as did
instanceof.
Object methods
Every object inherits these from Object.prototype:
| Method | Does | Player |
|---|---|---|
toString() | Gives the object as a string, by default "[object Object]". | 5 |
valueOf() | Gives the object’s primitive value, or the object itself. | 5 |
addProperty(name, getter, setter) | Makes a property whose reads call getter and whose writes call setter with the new value. A null setter makes it read-only. On a prototype it applies to every instance. | 6 |
watch(name, callback, data) | Calls callback(name, oldValue, newValue, data) when the property is set; its return value is what gets stored. | 6 |
unwatch(name) | Removes a watch. | 6 |
hasOwnProperty(name) | True if the object itself has the property, not through its prototype. | 6 |
isPropertyEnumerable(name) | True if the property exists and shows in for..in. | 6 |
isPrototypeOf(obj) | True if this object is on obj’s prototype chain. | 6 |
An object may also have a __resolve function (Flash Player 6), called
with the name whenever code reads a property the object does not have; its return
value is used instead.
Extending the built-in classes
Methods added to a built-in prototype appear on every object of that kind, including movie clips. Flash 5 code used this widely, since a movie clip symbol could not have a constructor of its own:
MovieClip.prototype.fadeOut = function (step) {
this._alpha -= step;
if (this._alpha <= 0) this._visible = false;
};
Array.prototype.contains = function (value) {
for (var i = 0; i < this.length; i++) {
if (this[i] == value) return true;
}
return false;
};
.as
files.Added methods show up in for..in loops over those objects. The
undocumented function ASSetPropFlags(object, names, set, clear) hides them:
flag 1 hides a property from for..in, 2 protects it from
delete and 4 from being overwritten. Flash’s own built-in properties carry
these flags.
Classes for movie clip symbols
Flash MX let a library symbol have its own constructor. The symbol is given a linkage
name, by ticking Export for ActionScript, and in an #initclip block the
constructor is linked to the symbol’s name. Every instance of the symbol, placed on the
stage or made with attachMovie or duplicateMovieClip, is then
made by that constructor, with no arguments, and inherits its prototype:
#initclip
function Button3D() {
this.gotoAndStop("up");
}
Button3D.prototype = new MovieClip();
Button3D.prototype.onRollOver = function () { this.gotoAndStop("over"); };
Button3D.prototype.onRollOut = function () { this.gotoAndStop("up"); };
Object.registerClass("Button3D", Button3D);
#endinitclip
Button3D.The constructor does not inherit MovieClip’s methods unless its prototype is linked
to MovieClip’s, as here. Registering null removes the link for later
instances.