"not a Date object" vs. "not an object with [[Class]] of ''Date''"

Dmitry A. Soshnikov dmitry.soshnikov at gmail.com
Sat Oct 2 01:43:52 PDT 2010


  In the same success it may be a simple very-generic meta-constructor 
(that is, Object.create) which may accept a className. That what have 
been discussed many times (including the only approach for today with 
injecting with __proto__), including in the recent talk 
https://mail.mozilla.org/pipermail/es5-discuss/2010-September/003708.html.

E.g.:

Object.create({
    prototype:<...>,
    class: "Array",
    descriptor: {
      ...
    }
});

or (the current, but extended way -- which won't bring backward compats issues)

Object.create(prototype, descriptor, "Array");


For what to create a proxy? It's only for catch-traps (yes, it may be 
used additionally to create a _catcher_ with "Array" [[Class]], but 
without additions -- i.e. if a user wants just to inherit from 
Array.prototype and to have all arrays' stuff -- proxies are not needed 
to him).

Dmitry.

On 02.10.2010 8:30, Tom Van Cutsem wrote:
> We have previously discussed the Proxy.create(handler, proto, 
> className) design and I think it's feasible. One issue is what should 
> happen to the proxy's [[ClassName]] when it becomes fixed. In the 
> current design, a fixed object proxy can be made indistinguishable 
> from a regular object. That's no longer the case if the fixed proxy 
> should retain its custom [[ClassName]] (which I think is desirable).
>
> That said, if proxies would be able to virtualize something like 
> [[ClassName]], I think the array subclassing use case can be supported 
> as follows (I'm sure there's a much better way to do this, but this is 
> just a proof-of-concept):
>
> function createArray(proto, initArray) {
>   // proto is assumed to delegate to Array.prototype
>   // initArray is assumed to be a real Array
>   var handler = {
>     get: function(r,n) {
>       if (!initArray.hasOwnProperty(n)) {
>         return proto[n];
>       } else {
>         return initArray[n];
>       }
>     },
>     set: function(r,n,v) {
>       return initArray[n] = v;
>     },
>     // other traps
>   };
>   return Proxy.create(handler, proto, "Array");
> };
>
> var SubArray = Object.create(Array.prototype);
> SubArray.last = function() {
>   return this[this.length - 1];
> };
>
> var myArray = createArray(SubArray, [1,2,3]);
> myArray.length; // 3
> myArray.last(); // 3
> myArray[10] = 42;
> myArray.length; // 11
> myArray.last(); // 42
> Object.prototype.toString.call(myArray); // [object Array]
> myArray instanceof Array; // true
> myArray.toString(); // 1,2,3,,,,,,,,42
>
> I tested this in a recent tracemonkey shell with support for Proxies 
> and it seems to work (except that currently, of course, proxies cannot 
> virtualize [[ClassName]] so the proxy-array still prints as [object 
> Object])
>
> 2010/10/1 Juriy Zaytsev <kangax.dev at gmail.com 
> <mailto:kangax.dev at gmail.com>>
>
>
>
>     On Fri, Oct 1, 2010 at 10:00 PM, Oliver Hunt <oliver at apple.com
>     <mailto:oliver at apple.com>> wrote:
>
>
>         On Oct 1, 2010, at 6:55 PM, Brendan Eich wrote:
>
>         > On Oct 1, 2010, at 6:24 PM, Oliver Hunt wrote:
>         >
>         >> I really don't like the idea of using proxies simply to
>         essentially create an array with a custom prototype.
>         >
>         > Implement proxies, then we'll talk :-P.
>         >
>         >
>         >> My understanding of what is wanted (in terms of subtyping
>         an array) is an ability to have something like
>         >>
>         >> var arr = new MyArray()
>         >>
>         >> Where 'new MyArray' behaves in essentially the same manner
>         as 'new Array', however it produces an object along the lines of
>         >>
>         >> <an array instance> <- <a custom prototype> <- <array
>         prototype>
>         >
>         > I don't think the use-case is satisfied by a direct Array
>         instance, whatever its proto. That's the rub.
>
>         What part of the use case is not covered?  From reading the
>         blog post (which suggests something similar to this) kangax
>         says the problem with this solution is the use of the
>         non-standard __proto__, not that it doesn't achieve the
>         desired result
>
>
>     Object.create([]) doesn't solve the problem of subclassing an
>     array, since created object is still a plain Object object and so
>     has [[Get]] and [[Put]] that act like Object's ones, not Array ones.
>
>     var o = Object.create([]);
>     o[2] = 'x';
>     o.length; /* 0, not 3 as it should be */
>
>     o.length = 0;
>     o[2]; /* "x", not undefined as it should be */
>
>     In ES3 (w/o extensions) you can't do much about it, but in ES5
>     it's possible to fiddle with length getter/setter to make object
>     act like an array (the performance of such implementation turns
>     out to be incredibly slow, for obvious reasons).
>
>     So now when you solved "magic" length property (considering that
>     we're in ES5), and have a plain Object object with [[Prototype]]
>     referencing Array.prototype, you still have immutable [[Class]].
>     So Array.isArray would return false for this pseudo-array object
>     (it could be somehow overwritten to account for it, but this is
>     kind of getting too far); and then there are places in spec, where
>     wrong [[Class]] ("Object", not "Array") will make for a completely
>     different outcome. For example, JSON.stringify:
>
>     var o = Object.create([]);
>     o[2] = 'x';
>
>     JSON.stringify(o); // "{"2":"x","length":0}" not [null,null,"x"]
>
>     Settable [[Prototype]] helps because you can just create an array
>     object, then inject something into its prototype chain (right
>     before Array.prototype). And that extra object can have any
>     methods you wish on subarray instances — all without polluting
>     global Array.prototype.
>
>     [...]
>
>     -- 
>     kangax
>
>     _______________________________________________
>     es-discuss mailing list
>     es-discuss at mozilla.org <mailto:es-discuss at mozilla.org>
>     https://mail.mozilla.org/listinfo/es-discuss
>
>
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20101002/cdb12237/attachment.html>


More information about the es-discuss mailing list