And one more thing to note, is that "Array.create" in general (if not to say -- /only/) is for the case of having objects which [[Class]] is "Array". It's very inconvenient (because of default property values of the descriptor) to define an array's elements with this function (I've updated the source with "Array.create" and the example):

var baz = Array.create(bar, {
// array elements (very inconvenient)
0: {value: 1, writable: true, enumerable: true, configurable: true},
1: {value: 2, writable: true, enumerable: true, configurable: true},
2: {value: 3, writable: true, enumerable: true, configurable: true},
// methods
info: {
value: function getInfo() {
return [this.length, this.size, this.count].join(",");
}
}
});

Dmitry.

On 03.10.2010 13:47, Dmitry A. Soshnikov wrote:
On 03.10.2010 1:56, Andrea Giammarchi wrote:
this.push.apply(this, [1, 2, 3]);

... mmmm, Dmitry, WTF :D

this.push(1, 2, 3);

easy :P


Ah, it was copy-pasted from more generic case when data came from arguments.

I still don't like the idea of "injectable [[Class]]" for user defined objects ... JS follows massive cross libraries approach

I just wanted to make it more generic (since Brendan and Tom were saying about "className" parameter for "Proxy.create"; so I made it for for "Object.create"). In less generic case, "Array.create" can be enough.

But because in JS prototype-based and class-based techniques are combined (including some Java's class-based syntactic constructs which lead to semantic meaning), the logical semantics in general may look also "broken". E.g.

foo instanceof Array // false

but at the same time:

Array.isArray(foo) // true

And these are quite normal situations (see the last lines in my code) with combining semantics of class- and proto-based approaches. Actually, this is what about the title of this thread.

P.S.: and regarding Array.create, it can be easily implemented in terms of abstaction with "Object.create" with accepting the "className", or more desugared and ad-hoc:

Object.defineProperty(Array, "create" {
  value: function (proto, desc) {
    var res = [];
    res.__proto__ = proto;
    return Object.defineProperties(res, desc);
  }
});

Of course, at implementation level it will look like (in generic case):

1. Let O be a new native ECMAScript object .
2. Set the [[Class]] internal property of F to /className/.
3 ...

Or in exact case can be so:

1. Let obj be the result of creating a new object as if by the expression new Array() where Array is the standard built-in constructor with that name.
2. Set the [[Prototype]] internal property of obj to O.
3. ...

Dmitry.

... please don't create a chaos even worst than the one we already have with randomly extended native prototypes.

Regards,
    Andrea Giammarchi


On Sat, Oct 2, 2010 at 11:05 PM, Dmitry A. Soshnikov <[email protected] <mailto:[email protected]>> wrote:

     On 03.10.2010 0:58, Dmitry A. Soshnikov wrote:

         On 03.10.2010 0:51, Brendan Eich wrote:

            On Oct 2, 2010, at 6:49 AM, Jorge wrote:

                On 02/10/2010, at 15:29, Brendan Eich wrote:

                    On Sep 6, 2010, at 1:43 AM, Dmitry A. Soshnikov
                    wrote:

                        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).

                    Proxies are required to update length to be one
                    greater than index (property name-string P such
                    that ToString(ToUint32(P)) == P and ToUint32(P)
                    is not 2^32 - 1) when setting an indexed
                    property. Array's magic [[Put]] is not inherited.

                Why not simply spec an Array.create() ?

                -no need to redefine what an array is.

            It's not clear from kangax's blog post that an array with
            an extra object on its prototype chain before
            Array.prototype is enough, but if it is, then yes:
            Array.create is simpler and more direct than using proxies.


                -no need to learn new concepts ( we're used to
                Object.create() already )

            There's definitely a new concept here. Right now you
            can't create an array instance whose [[Prototype]] is not
            some Array.prototype. Array.create changes that.


                -easy to grasp, expected behaviour.
                -it's a 3-liner that would take no more than 3
                minutes to implement in JS in any current UA.
                -it would just need to be in the ES specs.

            "3-liner", "3 minutes" and "just" need demonstration. Are
            you writing the code and spec patches? Talk is cheap :-|.
            Arrays are highly optimized in modern engines (up to some
            array sparseness limit). Adding a prototype object
            shouldn't hurt if the new proto-object contains no
            indexed properties, though.


        Off-topic: what's wrong with the es-archive? Take a look
        please:
        https://mail.mozilla.org/pipermail/es-discuss/2010-October/thread.html
        I sent reply with implemented extended Object.create and
        meta-constructor (meta-class) but it's not displayed there.
        Maybe it's not reached es-discuss at all? If it didn't (by
        some reason), consider this implementation
        (http://gist.github.com/607668). It allows to create objects
        of any [[Class]] with needed inheritance chains.


    Another variant btw, is just to set special internal property for
    the constructor. This property specifies the [[Class]] of objects
    created by the constructor.

    function Foo() {
     this.push.apply(this, [1, 2, 3]);
    }

    Object.setObjectsClass(Foo, "Array");

    var foo = new Foo();
    foo.length // 3
    Array.isArray(foo); // true
    // etc.


        Dmitry.

            /be

            _______________________________________________
            es-discuss mailing list
            [email protected] <mailto:[email protected]>
            https://mail.mozilla.org/listinfo/es-discuss



    _______________________________________________
    es-discuss mailing list
    [email protected] <mailto:[email protected]>
    https://mail.mozilla.org/listinfo/es-discuss




_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to