array like objects

Erik Corry erik.corry at gmail.com
Tue Dec 8 04:13:17 PST 2009


2009/12/8 Mike Samuel <mikesamuel at gmail.com>:
> It occurred to me after looking at the proxy strawman that it might
> help to nail down what "array-like" means in future drafts.  It isn't
> directly related to the proxy stuff though so I thought I'd start a
> separate thread.
>
> I've seen quite a bit of library code that does something like
>   if (isArrayLike(input)) {
>     // iterate over properties [0,length) in increasing order
>   } else {
>     // Iterate over key value pairs
>   }

This looks fairly broken to me.  If the object has enumerable
properties that aren't positive integers then they don't get iterated
over just because some heuristic says it's array-like.  If the
heuristic says it's array-like then we iterate over portentially
billions of indexes even if it is very sparse.

I think there are two different questions being asked here.

1) Does the object have the special semantics around .length?  This is
potentially useful to know and the normal way to find out doesn't
work.  Instanceof is affected by setting __proto__, yet the special
.length handling persists and instanceof doesn't work for cross-iframe
objects.

2) Is it more efficient to iterate over this object with for-in or is
it more efficient (and sufficient) to iterate with a loop from 0 to
length-1?  You can't implement functions like slice properly without
this information and there's no way to get it.

> but different libraries defined array-like in different ways.
> Some ways I've seen:
>    (1) input instanceof Array
>    (2) Object.prototype.toString(input) === '[object Array]'
>    (3) input.length === (input.length >> 0)
> etc.

These all look like failed attempts to answer one or both of the two
questions above.

>
> The common thread with array like objects is that they are meant to be
> iterated over in series.
> It might simplify library code and reduce confusion among clients of
> these libraries if there is some consistent definition of series-ness.
> This committee might want to get involved since it could affect
> discussions on a few topics:
>   (1) key iteration order
>   (2) generators/iterators
>   (3) catchall proposals
>   (4) type systems
>
> One strawman definition for an array like object:
>    o is an array like object if o[[Get]]('length') returns a valid
> array index or one greater than the largest valid array index.
>
> The need to distinguish between the two in library code could be
> mooted if for (in) on arrays iterated over the array index properties
> of arrays in numeric oder order first, followed by other properties in
> insertion order, and host objects like NodeCollections followed suit.

FWIW V8 does this for both arrays and objects.

But really for..in is pretty sick for arrays.  It will convert every
single index in the array to a string.  That's not something to be
encouraged IMHO.

-- 
Erik Corry


More information about the es-discuss mailing list