It's not just a feature of _javascript_... having to initialize instance level members in a class's construction is a characteristic of not only _javascript_, but any object oriented language I've ever seen. For instance, you can define a publically accessible property on a class in java or c#, but for the property getter method to be able to return a valid object reference at any point in the life of that object, you will have had to have set it to a valid object reference at some point prior to that, and usually you'd do that via initializing it during construction. This also has the added benefit of not allocating that memory until it's needed. In your js example you are assuming that there is magically going to be a new array allocated in memory, without you having to explicitly create one. The confusion can be expected though, since you can call methods of the prototype using this.someMethod(), and the "this" inside that method will refer to your instance, so it's natural to equate that to the classical model where each instance has it's own copy of that method... however you are still calling the prototype's method (there wasn't a new method copied into memory for your instance, it's just that your instance was bound as the callee to the prototype's method). That's the main difference between js's prototypical OO and the classical OO you're used to. All js object instances are sharing any access to their prototype's properties/members (be it methods or arrays or whatever).

In a language like java or c#, you CAN define a class like the following pseudo-code, and it will work as you were expecting your _javascript_ to work. Just keep in mind though that the compilation step in those other languages handles delegating the initialization of those variables to the object's internal constructor.

<pseudocode>
class someJavaOrC#Class
{
//leaving out actual getter/setter stuff for pseudo-code purposes
public Array myArray = new Array();

//constructor
public someJavaOrC#Class(string someInitialString)
{
myArray[0] = someInitialString;
}
}
</pseudocode>

On 10/25/06, Tobie Langel <[EMAIL PROTECTED]> wrote:

Thanks for clearing it up, it makes more sense like this.

So this should be considered as a feature of _javascript_ rather than a
Prototype bug.

I spent about half a day debugging a Class because of that
feature... ;-)

Regards,

Tobie


On 25 oct. 2006, at 03:14, Christophe Porteneuve wrote:

>
> Hey Tobie,
>
> Ah, I should have waited for breakfast caffeine to sink in before
> answering you, sorry :-)
>
> Prototype-defined fields are *not* static fields /per se/.  You would
> have to work on the constructor function's prototype to obtain
> something
> along those lines.
>
> The issue you run into here is due to how prototypes are used by
> the new
> operator.  Basically, every instance refers, by default, to the
> properties defined in the prototype, dynamically.  It's like they
> automatically proxy-delegate to the prototype, with the "this" binding
> going on for methods.
>
> Don't forget that object variables are just references.  If you do
> this
> in _javascript_:
>
> var a = [1, 2, 3];
> var b = a;
> a[1] = 'X';
>
> Then b will become [1, 'X', 3].  The "b = a" _expression_ just copies a
> pointer, so to speak.  Both variables reference the same object.
>
> It's fortunate that prototypes work this way, otherwise each instance
> would hold, for instance, a distinct copy of all methods and fields
> defined in the prototype.  Which would be a pretty bad way to go about
> defining methods.
>
> When you want per-instance fields that are still object references,
> you
> need to assign them to "this."-prefixed properties in the initialize
> function (called at construction time, see Class.create).  This way,
> each "new", calling initialize, will use a fresh value (i.e. a fresh
> object) for its field, therefore a unique reference.
>
> Look into Prototype and script.aculo.us code: you'll see that all
> prototype-defined fields are basically used as constants (e.g. the
> NODEMAP and ATTR_MAP fields in Builder).  All per-instance fields are
> assigned, directly or indirectly, from the initialize functions.
>
> As for this code:
>
> Tobie Langel a écrit :
>>>> var Tester = Class.create();
>>>> Tester.prototype = {
>>>>    initialize: function(str) {
>>>>       this.string = str;
>>>>    },
>>>>    string: ''
>>>> }
>
> The last string definition is useless: it's going to be overridden
> locally by every instance, because of the initialize function, that
> guarantees each instance has its own reference.
>
> I hope this makes it a bit clearer.
>
> --
> Christophe Porteneuve aka TDD
> [EMAIL PROTECTED]
>
> >






--
Ryan Gahl
Application Development Consultant
Athena Group, Inc.
Inquire: 1-920-955-1457
Blog: http://www.someElement.com
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs
-~----------~----~----~----~------~----~------~--~---

Reply via email to