What are the implications of this statement on the discussion of "Class
Methods" in JavaScript? In particular I am looking at page 126 of
JavaScript: The Definative Guide 4th ed. In the example, he has a
class called "Circle" and wants a class menthod called "max".
function Circle(radius){ stuff }
function Circle_max(a,b){ stuff }
Circle.max = Circle_max;
This example seems like a real mess. Why clutter the global
namespace with Circle_max?
Yes, why do that? One of the reasons that JavaScript the Definitive
Guide is only the least bad javascript book available.
Maybe there is some other reason but given that we
probably will only ever call Circle.max we have two better
options
Option 1 directly create a class method
function Circle(radius){ stuff }
Circle.max = function(a,b){ stuff };
Option 2 use a function instead of a class method
function Circle(radius){ stuff }
function Circle_max(a,b){ stuff }
In some languages, like Java, Option 1 would allow Circle.max
access to class variables. I think that this is not really an issue
in JavaScript
It could be an issue as - Circle.max() - could access other properties
of the constructor through the - this - keyword.
because nothing is private, true?
Well, things put into closures can be restricted in their accessibility
in ways that can resembles notions of 'private'.
However Option 1 will have slower execution speed because the
interpreter must resolve the '.' every time we use Circle.max().
The overhead per dot is not that great so how significant it is depends
a bit on how often you call the static method, and generally static
methods are not used that often. My issue with it is the number of dots
in a simulated namespace and the frequency with witch they would need
to be resolved.
So we could/should just use Option 2 which doesn't have much
namespace collision possiblity anyway.
Not necessarily. The concept of methods that are 'of the class' is well
expressed by making the methods properties of the constructor. If the
functions that are placed in that role really are suited then a small
overhead on the infrequent occasions that they would be referenced
doesn't seem like too great a cost to pay for the ability to associate
genuinely related facilities in a well defined unit.
There are many functions that could be strongly related to a particular
'class', such as virtually any function that acts upon multiple
arguments that must be instances of that 'class' (for example, a
compare function for use when sorting arrays of Circle instances), or
functions that implement concepts closely related to objects of a type
but not necessarily instances of that type (such as a method retiring
the surface area of a circle given its radius).
Where the namespace simulation may have:-
Something.Circle
- the existence of that initial - Something - implies that there may be
more than one 'Circle' in the system, and if they are well named the
implication would be that one or other would be redundant and that one
could be removed and the other used, or an amalgam of the two called
'Circle' would be more appropriate.
So what the heck was he arguing about when he said on page 126 that
"associating these function with a class gives them a convenient niche
in the JavaScript namespace and prevents namespace collisions."
It does prevent namespace collisions. The method in question is called
'max', which happens to also be the name of a static method of the Math
object.
There is no real benifit and a small perfomance decrease.
<snip>
There is a benefit, but the simulated namespace notion takes avoiding
namespace collisions far beyond collecting related functionality.
Exaggerating the performance decrease while addressing an issue that is
not nearly significant enough to justify such an extreme response.
Richard.