For those of you uber coders, this may seem trite, and “duh”. To me, though, I’m still learning, so I thought it was kind of a neat step in my education.
I found a use for putting properties on prototypes Sunday. I was coding about 6 classes who each had similiar properties, but a few had 2 or 3 that were different as well as all having about the same defaults. A lot of these properties won’t really get set either, therefore, not causing the instance of the class to get it’s own copy.
So, I put them all on prototype because:
– all 6 classes have them
– most classes only modify half of the properties to be different from the defaults
– majority of instances will only read the properties, not set them resulting in very few local instance copies
Ever since I learned that prototpye properties get transferred to local copies upon a setting of that property, I was distraught at how to implement constants. I then found if I just put my functions on prototype, but all of my properties in the constructor, things worked great. Glad to know I can still save some memory this way!
Cool idea! I think you could also use your own custom “init” method inside of a constructor and pass that on in other objects constructors, changing the arguments to fit. Still your way is cleaner I believe.
Again cooooool.
Another good thing is that it works the same for addProperty. Also, quick tip: you can use the hasOwnProperty method to check if a property has been locally defined in the class instance.
Class = function() {};
Class.prototype.addProperty(“prop”,
function() {
return this.$_prop;
},
function(v) {
this.$_prop = v;
}
);
Class.prototype.prop = “defaultValue”;
cInstance = new Class();
trace(cInstance.prop);
trace(cInstance.hasOwnProperty(“prop”));
That’s actually what I did with one class, QuasiNoob. It had some weird variation, so I just did that in the init. Worked pretty well and didn’t break the mold.
That’s pretty cool Jonas. I’ll have to experiement on one my classes to see how she reacts. There are a few, I think, that could benefit from being a getter/setter.
Yeah… I’ve been using this:
Class = function() {};
funtion() { // yeah, it doesn’t have a name :)
this.prop = “defaultValue”;
}.call(Class.prototype);
But it’s not as clean as Jesse’s method… =)
This is also a far better way of setting default params for components that can have parameters set in the property inspector. By putting them in the prototype, the user won’t have to worry about having to include them with attachMovie.
Well, sort of.
I do this in my components in the init:
<pre>
this.prop = (this.prop == null) ? “default” : this.prop;
</pre>
You could also just:
<pre>
this.prop = “default”;
</pre>
And if the user does:
<pre>
this.attachMovie(“TestSymbol”, “test_mc”, 0, {prop: “myValue”});
</pre>
Their init object value will over write the default. Your right, though, prototype is a lot cleaner. I hadn’t thought about using it that way to save time. Good idea!
One thing I will be teaching at my ff session is exactly this, its best to put defaults in the prototype object. I 99% of the time define all my properties there anyway for readability and also to be concise. It can get quite tricky to override a property when the constructor sets it. A good example if the FListBox which sets its itemSymbol in the constructor and then builds the listbox, if it was getting that property from the prototype object the extending class could much more effeciently changed the symbol…
During FF i was in part of Colin Moock’s session and noticed something that he does which I have since started doing. I have always declared my default properties in the prototype, but that never included MovieClips. Colin actually declares his MovieClips/TextFields to null. This has a benefit of making it easy to find what MovieClips are used by a Class.
link: http://moock.org/webdesign/lectures/ff2003Workshop/slide06.html
Gregs pretty much hit the nail on the head, in that really the prototype.property is mainly useful for readability and to simply state “these are the components default properties”.
The pro’s / con’s of prototype.property are very minor in that the “this scope” and the “prototype.property” are accessible both ways, only one requires you to declare them within an “init()” style method (or whatever method you wish to use) and the other doesn’t need to have a sub-contructor method (great for simple components that do not require an init()).
The advantage of the “this.scope” with an “init()” is that you can basically re-initialize a component at any given time, where as the prototype.property would need a similiar method to be created that handles the “reset” capabilities (which at the end of the day, is init() only differently named?)
I dunno, I’ve used them both and haven’t noticed any increase in speed or “inheritance” as at the end of the day unless you use the ASSetProps to hide/readonly etc your properties, they are still accessible by elements outside of the component.
I just find it a clean way to simply state “default readonly” properties that never have a setter method attached to them.
The way I see it, the ‘prototype’ properties are the shared class properties, ‘static’ in C#, Java and C++, and the object properties are regular instance properties.
So, I always write the member functions in the prototype, since these are ‘class properties’. Then I can also override a function implementation in an object instance and get polymorphism.
I was playing with __resolve and realized we could do the following. I’d use it if __resolve wasn’t undocumented. Hmm… This leads me to a question: is __resolve defined in ECMA-262? Just wondering if anybody knows the answer (I’m too lazy to search the big PDF now)… =)
Class = function(name) {
this.name = name;
};
Class.method = function() {
trace(this.name + “.method()”);
};
Class.prototype.__resolve = function(p) {
return this.constructor[p];
};
cInstance = new Class(“cInstance”);
cInstance.method();
Hey Anu/all,
static in c# and the example jesse is giving us are a little different.
When declaring a variable on the prototype it is true that all instances of the class will reference that value. However there is no way to modify that reference per instance with out it becoming an instance of the object you are modifying. In order to do this in Flash MX you?ll need to setup a getter/setter method and use the keyword ?constructor?:
function MyClass(){}
MyClass.prop = 1;
MyClass.prototype.getProp = function(){
return this.__proto__.constructor.prop;
};
MyClass.prototype.setProp = function(value){
this.__proto__.constructor.prop = value;
};
function MyClass2(){}
MyClass2.prototype = new MyClass();
a = new MyClass();
b = new MyClass2();
a.setProp(50);
trace(a.getProp());
trace(b.getProp());