array like objects

Garrett Smith dhtmlkitchen at gmail.com
Mon Dec 14 10:43:39 PST 2009


On Mon, Dec 14, 2009 at 9:34 AM, Mike Samuel <mikesamuel at gmail.com> wrote:
> 2009/12/13 Garrett Smith <dhtmlkitchen at gmail.com>:
>> On Sun, Dec 13, 2009 at 10:31 AM, Mike Samuel <mikesamuel at gmail.com> wrote:
>>> 2009/12/12 Garrett Smith <dhtmlkitchen at gmail.com>:
>>>> On Sat, Dec 12, 2009 at 4:04 PM, Mark S. Miller <erights at google.com> wrote:
>>>>> On Sat, Dec 12, 2009 at 3:38 PM, Garrett Smith <dhtmlkitchen at gmail.com>
>>>>> wrote:
>>>>>>
>>>>>> On Sat, Dec 12, 2009 at 2:59 PM, Mark S. Miller <erights at google.com>
>>>>>> wrote:
>>>>>> > Are we really this stuck? Can anyone think of a reliable, portable, and
>>>>>> > fast
>>>>>> > ES3R test that tests whether a property is enumerable, whether it is
>>>>>> > inherited or not?
>>>>>> >
>>>>>>
>>>>>> Not stuck. Why do you care if |length| is enumerable?
>>>>>>
>>>>>> If a standard |for| loop is used, it doesn't matter.  Why anyone would
>>>>>> want to use |for in| for something that is arrayLike?
>>>>>
>>>>>
>>>>> |for in| is not my concern. I wish a predicate that has little chance of
>>>>> false positives against legacy ES3 user constructed objects.
>>>>
>>>> Why the need to distinguish between a user-defined object that is
>>>> intended for iteration vs one that is not? The program should already
>>>> know. If the needs of a program are to iterate over an object's
>>>
>>> If programmers only wrote programs that would be true.  But they also
>>> write libraries for consumption by other programmers, and many come
>>> from languages that encourage duck-typing : if it enumerates keys like
>>> a duck ...
>>>
>>>
>>
>> What well-designed piece of code has absolutely no idea what its input is?
>
> Noone is talking about code that has absolutely no idea what its inputs are.
> Please see my mail in this thread from 10:10 PST of 8 Dec for examples
> of code that knows that an input is either an array-like collection or
> a map-style collection but that use different definitions of the
> former.
>

You mentioned several code examples earlier:

Please see the thread where I mentioned "mired in the bowels of
today's javascript libraries".

Those examples are vague. They mostly try to address all possible
cases, but don't do a very good job when the argument is a Host
object. The fact that these things are considered reliable is an
indication to the poor understanding of javascript.

Take a snip from one of your shining examples:

|       dojo.isArray = function(/*anything*/ it){
|               //      summary:
|               //              Return true if it is an Array.
|               //              Does not work on Arrays created in
other windows.
|               return it && (it instanceof Array || typeof it ==
"array"); // Boolean
|       }

That the method accepts *anything*' and returns anything. If - it - is
falsy, such as (false, null, undefined, 0, ""), then the inupt itself
is returned. OTherwise there is a check to - it instanceof Array -
which will always be false cross-frame/window. Third, there is typeof
it == "array", which will always be false. ALthough it is funny to see
how many mistakes dojo can cram into a single line of code, the fact
of the matter is that Dojo authors are not competent or knowledgeable
of ECMAScript.

Keep going?  OK...

| dojo.isArrayLike = function(/*anything*/ it){
|        //      summary:
|        //              similar to dojo.isArray() but more permissive
|        //      description:
|        //              Doesn't strongly test for "arrayness".
|        //              Instead, settles for "isn't a string or
|        //              number and has a length property".
|        //              Arguments objects and DOM collections
|        //              will return true when passed to
|        //              dojo.isArrayLike(), but will return false
|        //              when passed to dojo.isArray().
|        //      returns:
|        //              If it walks like a duck and quacks like a
|        //              duck, return `true`
|        // return it && it !== undefined && // Boolean
|        // keep out built-in constructors (Number, String, ...)
|        // which have length properties.
|                !d.isString(it) && !d.isFunction(it) &&
|                !(it.tagName && it.tagName.toLowerCase() == 'form') &&
|                (d.isArray(it) || isFinite(it.length));
| }

So we have a function which again takes *anything* and passes
*anything* to d.isString d.isFunction which can be assumed to be
similar in quality to their isArray function. Next, exclude any object
that does has a tagName property "form" (case-insensitive). Finally,
return true if d.isArray || isFinite(it.length). That includes
textNodes, comment nodes, and probably a ton of other Host objects.

The dojo.isArrayLike method tries to do something with anything, isn't
very clear about what it does, and creates confusion by being posed as
something competently written.

Copying such things is obviously a poor idea. Basing APIs on such
things is part of the "death spiral". and I'm out of time.

Regards,

Garrett


More information about the es-discuss mailing list