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

Reply via email to