if O is an Array object
On 2010-09-24, at 18:11, Jorge wrote:
So b is truly a subclass of Array, not a fake one.
I stand corrected. At some time in the past, this did not work for me. Apparently things have improved!
Thanks.
On 25/09/2010, at 08:39, Brendan Eich wrote:
On Sep 25, 2010, at 1:51 AM, Jorge wrote:
On 25/09/2010, at 01:28, P T Withington wrote:
On 2010-09-24, at 18:11, Jorge wrote:
So b is truly a subclass of Array, not a fake one.
I stand corrected. At some time in the past, this did not work for me. Apparently things have improved!
But you are right too: neither .proto nor Array.create() are in the specs, so there's no way to subclass an Array in ES5.
ES5 supports initializing proto on a new object, just not setting the prototype of an object after it has been created:
var arrayLike = Object.create([]);
But that's exactly what P T Withington was calling a fake array. To make it a true Array you'd need ES5 to have an Array.create() or .proto, because :
a= Object.create([]) ; a[2]=27 ; [a.length, a] -> [ 0, [undefined, undefined, 27] ]
And: a.length= 1 ; [a.length, a] -> [ 1, [undefined, undefined, 27] ]
A true Array.create() would be:
function Array.create (proto) {
if ( !(proto instanceof Array)) { throw Error("Proto must necessarily be an instance of Array"); }
var newArray= []; // <- get the special [[ put ]] newArray.proto= proto; return newArray; }
That, or an inheritable special [[ put ]], as you have said before:
On 24/09/2010, at 23:26, P T Withington wrote:
classProto= []; classProto.method= function () {}; b= []; b.proto= classProto; // <- That's all that's needed : an Array.create() b.method -> function
b is an array:
Array.isArray(b) -> true
Its .length works: b.length -> 0
b.push(27) ; b.length -> 1
b[2]= 27 ; b -> [27, undefined, 27]
b.length -> 3
So b is truly a subclass of Array, not a fake one.
On 24/09/2010, at 23:26, P T Withington wrote: > On 2010-09-24, at 16:01, Dmitry A. Soshnikov wrote: > >> An object is array (if and only if by the spec) if its [[Class]] is "Array". Even if the object implements all the interface and has all invariants (such as "length" property) of a casual array. > > Which is a bummer. I've wanted to be able to subclass both Array and String in the past, and you can't. You can only fake it to a certain extent. classProto= []; classProto.method= function () {}; b= []; b.__proto__= classProto; // <- That's all that's needed : an Array.create() b.method -> function b is an array: Array.isArray(b) -> true Its .length works: b.length -> 0 b.push(27) ; b.length -> 1 b[2]= 27 ; b -> [27, undefined, 27] b.length -> 3 So b is truly a subclass of Array, not a fake one. -- Jorge.