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