If three is one running theme in your posts to this group it is that
your expectations don't match up very well with javascript.
I don't really think JavaScript was well designed. toString, for
example, should not be relied upon (OT) but ES requires it for many
methods, and even defines, in many cases, the implementation for
toString.
ES4 has a lot of changes. For example 1 global object -- a headache
saver, IMO.
Other things, like the lack of a DateFormatter, will continue to be
frustrating in those cases. Methods similar to those JR Stockton
proposed here are going into Date, though.
Wouldn't the implication of your previous statement be that if -
parseInt - was a method of the number constructor then its output would
be a Number object not a number primitive?
Agreed.
This also be justifiable placed on Integer.
We clearly have different opinions on API design. I argue that
XXX.parse should return an XXX because it seems obvious.
Yes.
An instance method of String object might"might" be expected. That's where I see the problem. it's like you
can't be certain what's coming out of it.
It is neither correct nor not correct. Rather it seems to be expedient
and harmless otherwise.
It would be incorrect on Date, right? Date.prototype.parseJSON :
Object - seems to violate principle of least astonishment.
I would think use case, side effects, and how the API is used would be
more relevant.
toSource isn't in wide use because it's proprietary, non-standard.
It's a useful feature, but the implication of changing Object's
interface to say it's serializable -- that's what I take issue w/.
That doesn't matter in context. The method exists, has existed for some
considerable time, and it has (and is having) no negative impact on the
use of objects in JavaScript(tm) or ECMAScript. Ignoring its existence
is sufficient, and any second similar serialising method can just as
effectively be ignored when not wanted with the same outcome.
As it stands javascript only has one object type, and augments that
object to create what then become its various built-in types. Then
programmers who want multiple 'types' of object set about augmenting the
native ECMAScript object into the various 'types' they want. In the end
there is still not actual distinction between the 'type' of these
objects beyond what has been done to them and how they will be used. And
that distinction comes from the programmer not the language.
If the programmer declares that 'these objects are data structures' and
'these objects are not' then that is his/her design decisions, but the
objects themselves are still all just the native ECMAScript object in
reality. Thus, even if all the objects have serialisation method (and in
JavaScript(tm) they already do) then the distinction between a 'data
structure' and 'not a data structure' may be no more than calling the
serialisation methods of the first and never calling it on the latter.
This is the reality of tiring to do OO programming in a language as
loosely typed as javascript. There is no 'type safety' and the
programmer is the one responsible for staying on top of that and
understanding how the notions of 'type' from their design are to be
used/handled in the resulting program.
Because the addition you are talking about makes no practical
difference. It does not introduce anything new (object serialisation has
been a reality for a considerable time already) and so its only
contribution to the ability of 'programmers' to do stupid things is
providing another Identifier that can be put after a dot and before an
arguments list without the result actually erroring on the spot.
Cross browser?
Then don't call it. Your tool tip manages to get by without you
calling - toSource - on it.
Well, clients might call it, and would be perfectly correct in doing
so. When Tooltip 2.0 comes out, then toJSONString -- a contract that
Tooltip was forced into -- has different results (which the Tooltip
author may have neglected to consider). Maybe the client sees the
difference right away, or maybe the cleint's app seems to be working
for a while and then they realize that the serialization is different,
and includes an x property but the _id property is different.
toSource doesn't describe the object's public interface except in a
minority of browsers.
These are examples of "misuses" of "for-in loops, or closures"?
Closures. I've got some explanation below of why it's confusing.
"Confusing code" can often be a matter of experience and knowledge. As a
relative novice you will tend to be confused by many of the more
advanced constructs used in javascript, and perceive some of those
constructs as strange. That is inevitably true for anyone coming anew to
any programming language.
It is also possible for code that is inherently strange and confusing
(to any audience) to be written in any programming language.
JavaScript seems to make confusing, strange code almost necessary.
It's more condusive to weird constructs (like my weird singleton you
mention below). It makes it awkward to do things that should be easy
and straightforward -- like private.
What is needed with of your response to my request for examples of
"misuses of for-in loop, or closures" is some evidence for "the Power
Constructor" and "the Module pattern" being such "misuses". Or even of
their being inherently "strange and confusing". Otherwise we are left
with your unsubstantiated assertions, and may be included to attribute
them as the result of ignorance on your part rather than being anything
of significance.
OK.
Developers on my last gig were seriously confused by the module
pattern and would think that it was a namespace or part of the
namespace. I was there till 8 or later many nights. 10 hour days
fixing this stuff, so yeah, pretty annoying. All this in an anti-XP
environment, developing a heavy, feature-rich, internal app, with
waterfall process.
YAHOO.namespace("foo.bar");
// WRONG: namespace converted to object.
YAHOO.foo.bar = (function(){
if(YAHOO.foo.bar.hasGlobal) {
}
YAHOO.foo.bar.
function baz(x){ return x; }; // Function with hasGlobal for
[[Scope]]
// 1100 lines or so snipped..
return {
hasGlobal : false,
// baz method which points to baz (3)
baz : function(x) { return YAHOO.foo.bar.baz(x): }// Function 3
with hasGlobal for [[Scope]]
}
};
Now if there had been better teamwork and communication (and a smarter
mgr), they could have realized that the module pattern was causing
problems the way they were trying to use it. That started to happen
after I got there (more communication, pairing up, daily standups, et
c).
I think my boss told me to "change as little as possible" and "don't
break anything." Very hard to work with this code and boss, which was
very non-modular.
It took quite a long time to convince these guys to break stuff up
into multiple files -- about 5 months. We ended up with 25-30 files/
page. Convincing them not to use the memory-intensive module pattern
was more difficult, though they did finally see the mistake in the way
they were using it previously. They had just grown accustomed to it.
Doug Crockford seems to be taking credit for this pattern. He's never
once mentioned Richard Cornford.
Take "the module pattern" (as I am largely responsible for its
existence); about 6 months into to the development of the module pattern
the question of singleton pattern implementations came up, and it
rapidly became obvious that the module pattern lent itself extremely
will to that particular application. So much so that most introductions
to the module pattern have employed a singleton pattern as their primary
demonstration of the application of the module pattern (including the
well-known YUI article, where the name got attached to the technique).
The guys at Yahoo use this pattern and got really confused by it, I've
gone into detail w/this on the ES4 list, and above. Anyway, this is a
little OT.
On your web site you have a section headed "Design Patterns" which seems
to contain a single article that is a singleton pattern implantation:-
<URL:
http://www.dhtmlkitchen.com/?tq=Design Patterns>
I like patterns, and the mindset taht goest into them (encapsulate the
parts that vary). I've used Factory, pub/sub, Command, and even State.
Haven't wrote them all out for JS, though.
- which I find strange, and many novices would certainly find confusing.
One of the main things about your code that I find strange is its
ham-fisted attempt to achieve a notion of 'private' for an exposed
'class' constructor. Having a constructor for an object that you only
intend to ever have one instance of is itself a strange design decision
in javascript, as an object literal is an ideal structure for defining
an object that will only ever be a single unique object instance. But
the really strange thing in your code is that it employs the
JavaScritp(tm) extension - Array.prototype.indexOf - method in the code
that is supposed to very that the 'class' constructor is not directly
used by external code, and so will not work at all with any JScript
versions. That is strange because any 'Design Pattern' that cannot be
used with IE browsers has virtually no commercial applications at all
and so is virtually worthless.
Another strange aspect of your implementation of "private" for the
'class' constructor is how trivial it is to subvert. All a programmer
has to do in order to use the singleton 'class' constructor directly is
first execute:-
Function.entryCheck = function(){return;};
Trivial to subvert, true, I actually sometimes forget in MY OWN CODE,
and reinstantiate when I really wanted JCO (just create one)_. that's
why I like the throw Error() over having a problem when you've got two
objects and the program expects no more than 1.
I'm really not satisfied with my "singleton" approach. A runtime error
is bad, and the other points you mention (confusing to others), the
constructor is accessible (not private), but has a doc comment that
says "private" (contradictory). The access modifiers in ES4 are really
what I want.
One more thing I should mention is that Thomas mentioned that there is
no Map in ES4. This is a false statement. Hopefully others won't be
confused by it. Just wanted to clarify. ES4 has Map<T,T>. The <T,T> is
parameterized, so can be var m:Map<String, Widget> = new Map(...)
Finally, I'm really glad to see that the TG1 group has decided that
Object.prototype.toJSONString is out, and have removed it from the ES4
spec.
Garrett