Reputation: 83
O.K., I made these two classes (foo
and bar
), each in their own .AS file. Both of these classes were saved in a package called custom
.
In an .FLA file I called "Sandbox", I put the following code in the timeline:
import custom.foo;
import custom.bar;
var f:foo = new foo("FOO");
var b:bar = new bar("BAR");
trace(f.valueOf());
trace(b.valueOf());
f.statement();
b.statement();
I got the following output:
FOO
BAR
Statement: the value is FOO
Statement: the value is BAR
Now, usually, I wouldn't think much of this, but look at the code for the classes...
Here is the foo.as
file (minus my comments):
package custom {
public class foo {
public var property:String;
public var value:String;
public function foo (par:String = "?") {
this.property = par;
this.value = this.valueOf();
return;
}
prototype.expression = function () {
trace ("Expression: the value is", this.property);
}
public function statement () {
trace ("Statement: the value is", this.property);
}
public function valueOf() {
return(this.property);
}
}
}
...and here is the bar.as
file (minus my comments):
package custom {
public class bar {
public var property:String;
public var value:String;
public function bar (par:String = "?") {
prototype.property = par;
prototype.value = prototype.valueOf();
return;
}
prototype.expression = function () {
trace ("Expression: the value is", prototype.property);
}
public function statement () {
trace ("Statement: the value is", prototype.property);
}
public function valueOf() {
return(prototype.property);
}
}
}
Why did I get the same results when I used prototype
instead of this
?
I find that, although this is a vexing question, it cannot be answered unless someone can tell me what prototype
actually means.
I know this
roughly translates to "this instance of this class", but... What does prototype
mean?
Upvotes: 3
Views: 904
Reputation: 411
ActionScript 3 is based on the ECMAScript Specification (formally ECMA-262), that specifies the same standard as for JavaScript.
Basically the specification describes the prototype
property of an object as a kind of blueprint that defines the initial properties of a new instance of that object when created with new
. You can understand the prototype
as the class object that holds definitions for any field and method (or function
if you want) which are copied to each instance during the behind-the-scene-process of new
.
Calling a method or accessing a field on the prototype
will call the original function or will access the original field of the "class"-object and not of the method or field copied into the instance. Therefore you will always get the same value from protoype.property
but different from your f.property
and b.property
because they are instances of foo
and bar
respectively, created with new
.
Some special behavior to know about prototype
is the following.
First, three examples for explaining the differences of using prototype and normal members:
public class Sample {
public function Sample() {
trace("this.test():", this.test()); // output: this.test(): member test
trace("this["test"]():", this["test"]()); // output: this["test"](): member test
}
public function test():String {
return "member test";
}
}
public class SampleWithPrototype {
public function SampleWithPrototype() {
trace("this.test():", this.test()); // COMPILER ERROR: there is no member 'test' defined.
trace("this["test"]():", this["test"]()); // output: this["test"](): prototype test
}
prototype.test = function():String {
return "prototype test";
}
}
public class SampleWithBoth {
public function SampleWithBoth() {
trace("this.test():", this.test()); // output: this.test(): member test
trace("this["test"]():", this["test"]()); // output: this["test"](): member test
}
public function test():String {
return "member test";
}
prototype.test = function():String {
return "prototype test";
}
}
Now the explanation: Copied instance properties of the prototype
object are accessible on instances only using the subscript operator (this["test"]
in the examples). They are not checked during compile-time and can be accessed only in this way. Accessing it with the .
-notation raises a compile-time error (SampleWithPrototype
).
When defining both a member using prototype
and a member using regular member definition mechanisms like public function ...
, the regular defined member shadows the protopype
-member, so it becomes inaccessible (SampleWithBoth
).
In addition: You can overwrite prototype.test
with anything you want during runtime, so each instance created from the class after test
has been overwritten provides the new behavior. And you do not need to mark your class with dynamic
.
Finally: I would not recommend using this features, because it can make your application unpredictable and hard to debug. Using the prototype
is not common in ActionScript unless you switch the compiler into the (much slower) ECMA-Standard mode (that is the non-strict mode). Then you will get the same behavior like you have in JavaScript.
Upvotes: 2
Reputation: 13151
Both AS3 & Javascript derive from the same ECMAScript.
In javascript prototype exists as the only means of extending an object & writing an Object Oriented JS.
It exists with the same meaning in AS3 as well.However in AS3, Adobe wrote the class structure, rendering the use of prototype extinct. So in AS3 you write classes & work with them as in any of the popular oop languages like C#/Java.
Upvotes: 0
Reputation: 17237
According to the official documentation:
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 the Flash 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.
Upvotes: 0