On Dec 15, 2009, at 8:46 AM, Jorge Chamorro wrote:
It's the same functionality provided by Object.create(), but for []
instead of {}.
Ah, that helps -- thanks. This is not exactly what Tucker showed,
though.
Tucker is looking for a way to compose custom [[Put]] with
prototype-based delegation. My reply suggested that if [[Put]] were
a property name, just like "length", and looked up along the
prototype chain, so that the default [[Put]] was in
Object.prototype, the custom Array [[Put]] that updates .length to
be one greater than the highest index were on Array.prototype (or
on [] in Tucker's example, but in general on the class prototype
would suffice), etc., then we would not need anything new like
Array.create.
The way I see it, the subclass' prototype object ought to come -
necessarily- before the Array.prototype object in the subclassed
instance's prototype chain. If not, every other existing and future
[] instances would be affected too. Also, because if not there would
be no way to create two different [] subclasses.
Sure. I was not describing Array.create or "subclasses", just
responding to what Tucker showed:
function MyArray () {}
MyArray.prototype = [];
It may be that Array.create could fit his use-case instead, but if the
idea is to make new user-defined *constructors* such as MyArray, then
Array.create does not necessarily help. The user-defined constructor
would have to return a new Array.create(MyArray.prototype) instance,
and it would be stuck with the non-configurable "own" properties
defined on Array instances.
This might or might not be desired; anyway, it's not exactly the same
as what you proposed in reply.
If for some reason you wanted/needed to override/shadow any/some of
Array.prototype's methods, isn't it that, in order to achieve that,
the subclass' prototype object ought to come before the
Array.prototype object in the instance's prototype chain ?
I don't believe I wrote otherwise.
That, or manually extending each and every instance with own
properties ?
AFAICS, anything that comes -in the prototype chain- after
Array.prototype would extend all the [] instances at once. But most
likely I'm missing something...
My point was that if [[Put]], which is part of what makes an Array
instance "array-like", were delegated, along with the other internal
methods in ES5 (which are of course specification devices, not
concrete implementation artifacts), then what Tucker wrote -- exactly
what he wrote -- would "work".
The reason it doesn't work is evident from a bit more REPL citing:
js> function MyArray () {}
js> MyArray.prototype = [];
[]
js> var a = new MyArray
js> a.length
0
js> a[9] = "length should now be 10"
"length should now be 10"
js> a.length
0
What I proposed instead (not seriously; it's more a Self _homage_ than
anything to add to a future JS/ES, at this point) was that setting
a[9] would look for [[Put]] in a, not find it, look in a.
[[Prototype]], which is [] above, not find a custom [[Put]], then look
in [].[[Prototype]] which is Array.prototype, and finally find the ES-
specified custom [[Put]] that advances length as needed.
When the Array [[Put]] was invoked, it would be passed a as the
directly referenced object, the receiver of the method call (aka |
this|). Thus, 'length' would be set directly on a by the Array [[Put]]
internal method.
In ES specs and real implementations, internal methods and various
corresponding implementation hooks are called based on [[Class]] of
the directly referenced object, in contrast. No lookup for internal-
method names that cannot be uttered in the source language is done.
But this ancient design decision means we have "host objects" that can
and do have inconsistent or even incorrect internal method suites.
/be
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss