On Jun 28, 2011, at 8:34 PM, Bob Nystrom wrote:
> I like the simplicity of this, but I'm not crazy about how it merges two
> distinct objects into one. TodayJS (and most class-based languages) let you
> distinguish two things:
(actually in the today's most widely used class-based languages (Java, C#, C++)
a "class" is no an object at all and don't have properties/fields/polymorphic
methods/etc. they really are just a scoping mechanism. What you are saying is
more typical of many dynamically typed class-based languages).
Note that the goal of the prototype as classes proposals is not to turn JS into
more of a class-based language. Instead it was to solve the same problem that
classes solve but in a manner that returns JavaScript closer to its original
prototype-based roots. This was covered in the message that started the
"Prototype as new new class declaration" thread
https://mail.mozilla.org/pipermail/es-discuss/2011-June/015135.html It is
probably worth while going back to review those first few messages to get a
better chance of what this proposal is really about.
While both the class-based approach and the prototype-base approach allow you
to describe an open ended set of similar objects via a named abstraction, the
key difference is in what you name. In the class based approach you name the
object that is responsible for creating new instances (the constructor) of the
set. In the prototype-based approach you name the prototypical instance of the
set.
The "two objects" you speak of is purely an artifact of how the class-bassed
approach works. It is not a fundamental characteristic of all OO languages.
When it is useful to have s separate factory object for creating the instances
of a prototype-based abstractions, prototype-based languages simply create
another object to act as the factory. that object can have private state,
addiional public properties for accessing canonical instances, etc.
In https://mail.mozilla.org/pipermail/es-discuss/2011-June/015195.html is
examine how the self language addressed various situations where "static
methods" might be used in a class-based langauges.
>
> 1. A set of properties relevant to the class itself.
> 2. A set of properties shared by each instance of the class.
>
> In a class-based language, #1 up there is "static" methods and fields. So
> when you do something like this in Java:
>
> Integer.parseInt("1234");
>
> The "parseInt" method isn't a method that you can call on an integer, it's a
> method you call on the Integer class itself.
In self, you would likely do exactly the above. Integer would be the name of
the prototypical integer object and that object would have a method named
parseInt.
You then can just say:
Integer.parseInt("1234"); //actually in self you would say: Integer
parseInt: '1234'.
or you can say
0.parseInt("1234");
or any other integer object that was conveniently available.
If you didn't want the ability to parse to be a method of integers you would
just create a factory object:
IntegerBuilder.parse("1234");
Why is this worse than a "static method"?
>
> In Javascript, those are properties on the constructor:
>
> function Point(x, y) {
> this.x = x; this.y = y;
> }
note that the above isn't a property of the constructor, it is the constructor.
It actually is a property of the prototype.
>
> Point.zero = function() { return new Point(0, 0); }
>
> Point.zero(); // "static" method.
It's all a mater of how you think of responsibilities. In a consistent
prototype based usage, the "zero" point would probably actually be the
prototypical point in which case you would access it simply as Pointl
>
> The second set of properties are properties on ".prototype" in JS: Its
>
> Point.prototype.flipX = function() {
> this.x = -this.x;
> }
>
> var p = new Point(1, 2);
> p.flipX();
> p.x // -1
>
> To me, those two sets are utterly distinct. This code looks pretty strange:
>
> Point.flipX(); // What x?
The x of the prototypical point named Point. As a prototypical point it has
all the properties of any other point instance including an x and y property.
(I'm ignoring the fact the a point abstraction with mutable x and y fields is
probably not a very good design).
In practice, you probably wouldn't call such a method on the prototype, so you
wouldn't see the above at all. But you could, that's what it means to be a
prototype-based language.
>
> var p = new Point(1, 2);
> p.zero(); // This works, but what does it have to do with 'p'?
probably as much as any other Point method that creates a new instance. Since
you probably really do want to have immutable points, that means most point
methods:
p.add(new Point(3,4)); //returns a new point with x=4, y=6
p.zero(); //return a point with x=0,y=0
But, similar to above, in practice you probably would seldom actually see the
latter. You would just see:
Point.zero();
>
> Your proposal would allow that, I think. For example, starting from yours:
>
> // Superclass
> var Person = {
> constructor: function (name) {
> this.name = name;
> },
> describe: function() {
> return "Person called "+this.name;
> }
> };
>
> I could do:
>
> var bob = new Person("Bob");
> bob.constructor("Fred"); // I guess I'm Fred now.
>
> Does the above seem strange to you too?
not particularly anymore so than
Bob("Fred"); //note no new
or
Bob.call(bob,"Fred")
Allen
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss