array like objects

David-Sarah Hopwood david-sarah at jacaranda.org
Fri Dec 11 16:32:03 PST 2009


Mark S. Miller wrote:
> On Fri, Dec 11, 2009 at 2:27 AM, Mike Wilson <mikewse at hotmail.com> wrote:
> 
>> I think Breton mentions something important here; the desire
>> to actually detect if something is an array or arraylike to
>> be able to branch to different code that does completely
>> different things for array[likes] and objects.
[...]
> 
> If we're looking for a convention that is
> * does not admit any legacy ES3R non-array non-host objects (to prevent
> false positives)
> * does easily allow ES5 programmers to define new array-like non-array
> objects
> * takes bounded-by-constant time (i.e., no iteration)
> * is a reasonably compatible compromise with the existing notions of
> array-like in legacy libraries as represented by previous examples in this
> thread
> 
> then I suggest:
> 
> function isArrayLike(obj) {
>   var len;
>   return !!(obj &&
>             typeof obj === 'object' &&
>             'length' in obj &&
>             !({}).propertyIsEnumerable.call(obj, 'length') &&
>             (len = obj.length) >>> 0 === len);
> }
> 
> Since getting 'length' may have side effects, this is written a bit weird so
> that this get only happens after earlier tests pass.

If you want to avoid side effects:

function isArrayLike(obj) {
  if (!obj || typeof obj !== 'object') return false;
  var desc = Object.getPropertyDescriptor(obj, 'length');
  if (desc) {
    var len = desc.value;
    return !desc.enumerable && (len === undefined || len >>> 0 === len);
  }
}

This allows any length getter without checking that it will return an array
index, but it still satisfies all of the above requirements.

However, I don't see why the check on the current value of length is
necessary. For it to make any difference, there would have to be a
*nonenumerable* length property on a non-function object, with a value
that is not an array index. How and why would that happen?

> And yes, I'm aware that this usage of Object.prototype.propertyIsEnumerable
> implies that catchalls must virtualize it in order for a proxy to be able to
> pass this test :(.

Same with Object.getPropertyDescriptor in the above.

-- 
David-Sarah Hopwood  ⚥  http://davidsarah.livejournal.com

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 292 bytes
Desc: OpenPGP digital signature
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20091212/b8b12d67/attachment.bin>


More information about the es-discuss mailing list