On Fri, Mar 12, 2010 at 13:13, skar <[email protected]> wrote:
>
> > this article should answer your question:
> >
> http://qooxdoo.org/documentation/1.0/antipatterns#reference_types_in_member_section
> >
>
> Derrell. Is this a qooxdoo specific problem or a problem
> in JS in general?
>
Hmmm... How to answer that...
What we're talking about here is a feature of the JavaScript language that
is very useful. Objects (including Arrays) can become very large. Instead of
passing copies of objects and arrays around, and taking the possibly large
amount of time required to make those copies, only a single copy of each
object is created, and when assigned to another variable or passed to a
function or method, a reference to that object is passed. For function
calls, this is typically referred to as "call be reference" instead of "call
by value." (Scaler types are passed by value.)
In the case of your question, you created a class like this (with a few
changes by me):
qx.Class.define("testproject.ArrayClass",
{
extend: qx.ui.basic.Atom,
construct : function()
{
this.base(arguments);
this.arr2 = new Array();
},
members :
{
elementsRemaining : 10,
arr : new Array()
}
});
What we have here is a JavaScript object (aka a "map") being passed to a
static function called qx.Class.define. The define() function creates a
JavaScript object prototype, which creates a new class, and uses the
provided map to initialize that class. The way that define() is implemented
puts member initialization into the prototype, so each instance of the class
gets initialized with the initial values from the members portion of the
map. The initial values are evaluated at define() time and placed into the
prototype.
Looking at the above example, you'll see this is very desirable to allow a
new instance of testproject.ArrayClass to have its elementsRemaining member
initialized to 10. This will occur automatically for each new instance of
testproject.ArrayClass since the prototype of this class had an
elementsRemaining member with a value of 10.
But what happened with the arr member? Its value, too, got evaluated at the
time that qx.Class.define() was called, so the prototype contains a *
reference* to that Array that was created. Each instantiation of
testproject.ArrayClass gets the reference to that same array in its arr
member, because the prototype had a reference to that array in the class'
arr member.
So is it a bug or a feature? It is certanly a JavaScript feature. I suppose
that one might have designed qx.Class.define() a bit differently, and placed
into the members portion of the map only a list of member variables
(implicitly asking that they each be added to the prototype with a value of
null), and requiring that all member variables be initialized in the
constructor. This would have prevented the "issue" (I like that word better
than "problem" in this context) that we're seeing here because there would
be no opportunity to have a reference type added to the prototype. On the
other hand, it would complicate the code (to a fairly large extent, with
many classes with lots of scaler initialization) by forcing initialization
of every member variable in the constructor, rather than in the much cleaner
representation of the members: section of the map.
So there are the pros and cons. That should provide some food for thought.
Cheers,
Derrell
------------------------------------------------------------------------------
Download Intel® Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
qooxdoo-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/qooxdoo-devel