On Fri, Dec 11, 2009 at 2:27 AM, Mike Wilson <mike...@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 just
> provide a better generic iteration construct then this part
> is lost, as I might even not be doing iteration in one of
> the branches.
>
> Certainly, solving this isn't easy, but it would be good if
> there was some direction taken by the WG to provide a
> standard way to detect arraylikeness without having to do
> iteration, so JS runtimes, browser host objects and JS
> libraries can follow this precedent.
>
>

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.

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 :(.

-- 
   Cheers,
   --MarkM
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to