To me it makes more sense to have functions constructors creating new
instances of classes as you described. It seems more consistent having
prototype chains and class inheritance being in sync as much as possible, as
they are both forms of inheritance. Right now, if an object is an instance
of a class it has the classes's prototype in the instance's prototype chain.
If D extends C, than instances of D have both C and D's prototype in the
prototype chain. It would really be nice if the converse were true, that is
if an object has C's prototype in it's prototype chain than it must be an
instance of C. Of course, this would not only be more consistent logically
because both forms of inheritance (class and prototype) would have the same
hierarchy, but it seems more consistent with ES3 behavior where instanceof
determinations are based upon prototype chains. "is" and "instanceof" would
have more similiar behavior (albiet still different). I suppose if __proto__
was still exposed as writable property programmers could still mess up the
whole consistency though.
Kris


On 7/2/07, Brendan Eich <[EMAIL PROTECTED]> wrote:

  On Jul 2, 2007, at 9:21 AM, Kris Zyp wrote:

 It appears (at least in the reference implementation) that one there is
an object that has a delegate object that is a typed object, that
overwriting members in the top instance is sometimes not possible. For
example:
class C { var x : String; }
c = new C;
function F() {}
F.prototype=c;
f = new F; // f.__proto__ = c
f.x =4;
If you do this c.x now equals "4", that is the value is not set in f, but
it goes up the prototype chain and sets 4 into x (and does implicit
conversion). I think I realize why this is being done. c is of type C, but f
is not of type C, but it still must maintain consistency in the typing of
its members (so instance method can be assured of the right types, I
presume). However, this seems that like quite unintuitive behavior for
JavaScript. Generally one would expect the statement f.x=4; to only affect
f, not f's delegate (c). Was it ever considered to enforce a system where if
f delegates to c, that f must be the same type (or subtype) as c? This could
be done by allowing [[Class]] definition to be inheritable from a delegate
(in this f would not define what [[Class]] it is, but would inherit it's
class definition from c which defines it's class to be C), and maintaining
prototype chain consistency with class inheritance.





If you want x to be a delegated and override-able "plain old" property,
not a fixture, declare C thus:


class C { prototype var x : String; }


Without prototype qualifying var, you get a fixture, and fixtures are
always fixed as to meaning and type constraint by type of their containing
class. That's their *raison** d'ĂȘtre*.


Having said that, I'll admit that your suggested change to the class
instantiated by (new F) given F.prototype = new C is interesting and
provocative. By default, ES4 as reference-implemented follows ES3 and makes
(new F) for all functions F creates a new Object instance. But native
constructor functions and classes can make instances of narrower types than
Object, obviously (Date, RegExp, etc.). And some built-in classes (at least
RegExp per ES3's spec, although no browsers follow this) have *prototype*
properties of type Object.


So there's an attractive symmetry in making F.prototype = new C cause (new
F) to instantiate C instances.


If we did this, you would still have fixtures overriding prototype
properties, but you would have a fixture per (new F) instance, not one in
the (new C) prototype instance as in your example (the one denoted by the
variable |c|). That would avoid the pigeon-hole problem. (You could also use
the prototype qualifier as in my counter-example.)


If we did this, you might also (or might not) want |dynamic| in front of
class C {...} in order to allow "expandos".


Still thinking, comments welcome.


/be

_______________________________________________
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss

Reply via email to