array like objects

Garrett Smith dhtmlkitchen at gmail.com
Sat Dec 12 12:29:06 PST 2009


On Sat, Dec 12, 2009 at 12:01 PM, Mark S. Miller <erights at google.com> wrote:
> On Sat, Dec 12, 2009 at 11:21 AM, Garrett Smith <dhtmlkitchen at gmail.com>
> wrote:
>>
>> On Fri, Dec 11, 2009 at 12:08 PM, Mike Wilson <mikewse at hotmail.com> wrote:
>> > Mark S. Miller wrote:
>> >
>> > If we're looking for a convention that is
>> > * does not admit any legacy ES3R non-array non-host objects (to prevent
>> > false positives)
>>
>> No native ES objects?
>>
>
> Native array and (currently) String wrapper objects do pass this test. No
> other ES3R natives objects can. Which native objects are you concerned
> about?
>

Any user defined native object e.g. a jquery object or something like:

{
  x : 10,
  length : 1.5
}


>>
>> > * does easily allow ES5 programmers to define new array-like non-array
>> > objects
>> > * takes bounded-by-constant time (i.e., no iteration)
>>
>> *What* takes bounded-by-constant time? The object's existence would
>> not take any time.
>>
> The execution time of this predicate. Actually, that's not necessarily true.

[snip]

Got it.  That means that the isArrayLike test itself is constant time.
That makes sense.

>>
>> > * is a reasonably compatible compromise with the existing notions of
>> > array-like in legacy libraries as represented by previous examples in
>> > this
>> > thread
>>
>> Can you please clarify what the problem area is a little more?
>>
>> > 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);
>> > }
>> >
>>

[snip]

>>  Is looks like "array like" is defined as an an object where "length"
>> is non-enumerable and numeric. What about [[Get]], [[HasProperty]] for
>> numeric property names?
>>
>> And why must the - length - property be an *own* property? Why could
>> length not be a getter in the prototype chain?
>>
>> Indeed many Mozilla DOM collections work this way:
>>
>> javascript: var cn = document.links; alert([cn.length,
>> ({}).hasOwnProperty.call( cn, "length")]);
>>
>> Mozilla elerts "80, false"
>>
>
> Not a problem. The proposed predicate does not test whether 'length' is own,
> only whether it is enumerable. A squarefree session on FF 3.5.5:
>
[snip]

Ah no, that is not correct, your isArrayLike *does* test to see
whether "length" is own.

Object.prototype.propertyIsEnumerable does not consider properties in
the prototype chain. In effect, propertyIsEnumerable is a test to see
if an object has *own* property that is also enumerable.

We discussed this back in ES4 proposal days, and I think I remember
that it was decided to keep the existing behavior (as unintuitive as
it may be) to not break existing code (some already broken things YUI
and some other libs were doing).

Also notice that the name propertyIsEnumerable deviates from standard
boolean predicate method naming convention. Flash AS apparently has an
isPropertyEnumerable (more standard boolean predicate name).

Garrett


More information about the es-discuss mailing list