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