Go Back   Rhinocerus > Newsgroup > Newsgroup comp.lang.java.* > Newsgroup comp.lang.javascript

Reply
 
Thread Tools Display Modes
  #31 (permalink)  
Old 12-19-2006, 12:48 AM
Jeremy
Guest
 
Posts: n/a
Default Re: Robust isArray() ?

Matt Kruse wrote:
> I'm seeking the most robust and backwards-compatible (ie, no instanceof)
> isArray function.
>
> Here's what I have:
>
> function defined(o) {
> return typeof(o)!="undefined";
> }
> function isArray(o) {
> // If these conditions aren't met, it certainly isn't an Array
> if (o==null || typeof(o)!="object" || typeof(o.length)!="number") {
> return false;
> }
> // Check to see if the object is an instance of the window's Array object
> if (defined(Array) && defined(o.constructor) && o.constructor==Array) {
> return true;
> }
> // It might be an array defined from another window object - check to see
> if it has an Array's methods
> if (typeof(o.join)=="function" && typeof(o.sort)=="function" &&
> typeof(o.reverse)=="function") {
> return true;
> }
> // As a last resort, let's see if index [0] is defined
> return (o.length==0 || defined(o[0]));
> };
>
> Suggestions?
>


If by "array" you mean something that can be iterated over with the
following construct:

for(var index = 0; index < myArray.length; index++)
alert(myArray[index]);

without error, then any object that has a non-negative numeric 'length'
property will satisfy your criteria.

As for your last test:
return (o.length==0 || defined(o[0]));

Consider the following:

var x = new Array();
x[5] = "garbanzo";
alert(typeof n[0]); //"undefined" in FF 1.5

I would instead check whether o[o.length - 1] is defined - if it's not,
then o has no reason to have length of o.length (however there is
nothing preventing you from explicitly setting the length of the array).

In the above example:

var x = new Array();
x[5] = "garbanzo";
alert(typeof n[n.length - 1]); //"string"

Jeremy

Reply With Quote
Alt Today
Advertising
 
and become member of Rhinocerus
Standard Sponsored Links

  #32 (permalink)  
Old 12-19-2006, 03:09 AM
Matt Kruse
Guest
 
Posts: n/a
Default Re: Robust isArray() ?

Jeremy wrote:
> If by "array" you mean something that can be iterated over with the
> following construct:
> for(var index = 0; index < myArray.length; index++)
> alert(myArray[index]);
> without error, then any object that has a non-negative numeric
> 'length' property will satisfy your criteria.


I suppose, but that doesn't mean that numeric indexes from 0..(length-1) of
the object are intended to hold any meaningful data.

> As for your last test:
> return (o.length==0 || defined(o[0]));
> Consider the following:
> var x = new Array();
> x[5] = "garbanzo";
> alert(typeof n[0]); //"undefined" in FF 1.5


That's why this case would already be trapped by the code about the final
test.

> I would instead check whether o[o.length - 1] is defined - if it's
> not, then o has no reason to have length of o.length


This might be logically true, but one could easily do:

var empty = [,,,,,];

--
Matt Kruse
http://www.JavascriptToolbox.com
http://www.AjaxToolbox.com


Reply With Quote
  #33 (permalink)  
Old 12-22-2006, 04:58 PM
VK
Guest
 
Posts: n/a
Default Re: Robust isArray() ?


Richard Cornford wrote:
> That is the basis of the
> test, but deleting the 'array index' member you have added to the array
> does not have any side-effects on the array's - length - property so it
> remains one greater then it was to start with.


Hum... indeed. That's kind of a silly behavior I did not notice before
- as I never used delete on array elements. IMO delete should work the
same way as delete someObject.someProperty - not keeping someProperty
with undefined value but _delete_ it as it never existed.
Well, it's easy to fix:

function isArray(obj) {
var ret = false;
var len = 0;

if (obj) {
len = parseInt(obj.length, 10);
if (len == len) {
obj[len] = 'probe';
ret = (len < obj.length);
obj.length = len;
}
}

return ret;
}


> Didn't you see my other reply to that test code with the standard
> javascript object that fools your " absolutely robust" into believing it
> is an array without its even inheriting the methods or an array? I
> suppose I had better post it again for your benefit:-
>
> function AnObject(){
> ;
> }
> AnObject.prototype = {
> length:{
> count:0,
> valueOf:function(){
> return this.count++;
> },
> toString:function(){
> return '0';
> }
> }
> };
> var obj = new AnObject();
>
> alert(('isArray(obj) = '+isArray(obj)));//alerts isArray(obj) = true;


What browser did you test it on? Of course it fails (false). As I said,
there is no technical way to implement compound property within
ECMAScript 3rd ed. It's not a teasing for an intellectual challenge,
just a constatation of a fact. Respectively this isArray is absolutely
rubust yet absolutely not needed with instanceof alive.

Reply With Quote
  #34 (permalink)  
Old 12-22-2006, 06:21 PM
Richard Cornford
Guest
 
Posts: n/a
Default Re: Robust isArray() ?

VK wrote:
> Richard Cornford wrote:
>> That is the basis of the
>> test, but deleting the 'array index' member you have
>> added to the array does not have any side-effects on
>> the array's - length - property so it remains one
>> greater then it was to start with.

>
> Hum... indeed. That's kind of a silly behavior I did not
> notice before - as I never used delete on array elements.


And you only needed to be told why your original - isArray - function
was inadequate three times before you tried it for yourself.

> IMO delete should work the same way as delete
> someObject.someProperty - not keeping someProperty
> with undefined value but _delete_ it as it never existed.


That is exactly what - delete - does do. I don't know what exactly
passes as testing with you but it doesn't appear to leave yo0u any
better informed.

> Well, it's easy to fix:
>
> function isArray(obj) {
> var ret = false;
> var len = 0;
>
> if (obj) {
> len = parseInt(obj.length, 10);
> if (len == len) {
> obj[len] = 'probe';
> ret = (len < obj.length);
> obj.length = len;
> }
> }
>
> return ret;
> }


You really don't understand what the code you write does, and even when
your faults are pointed out you just don't know how to correct them. You
have change code that modifies the - length - property of all the arrays
that are exposed to it into code that adds a new (or changes an
existing) property to (on) every non-array object it encounters that has
a numeric - length - property (which, at minimum, includes all String
and Function objects, plus many custom objects). A test function really
should not permanently modify the objects that it tests.

>>> It is absolutely not possible within the frame of
>>> ECMAScript 3rd ed.

>>
>> Didn't you see my other reply to that test code with
>> the standard javascript object that fools your " absolutely
>> robust" into believing it is an array without its even
>> inheriting the methods or an array? I suppose I had better
>> post it again for your benefit:-
>>
>> function AnObject(){
>> ;
>> }
>> AnObject.prototype = {
>> length:{
>> count:0,
>> valueOf:function(){
>> return this.count++;
>> },
>> toString:function(){
>> return '0';
>> }
>> }
>> };
>> var obj = new AnObject();
>>
>> alert(('isArray(obj) = '+isArray(obj)));//alerts isArray(obj) = true;

>
> What browser did you test it on?


Firefox, Opera and IE (though it is pure ECMAScript so would be expected
to work with all anyway). Why didn't you test it? Or why couldn't you
manage to perform such a simple test effectively?

> Of course it fails (false).


When the - isArray - function is the function that you posted and
declared "absolutely robust", that was:-

| function isArray(obj) {
| var ret = false;
| if ((obj) && (!(isNaN(parseInt(obj.length))))) {
| var len = parseInt(obj.length, 10);
| if (len == obj.length) {
| obj[len] = 'probe';
| ret = (len < obj.length);
| delete obj[len];
| }
| }
| return ret;
| }

- the result is exactly as I described; the alert is 'isArray(obj) =
true'. You could verify that by trying it yourself, as anyone else can.

> As I said, there is no technical way to implement
> compound property within ECMAScript 3rd ed.


As your whole "compound property" thing was a fiction with no reality
outside your own head anything you say on the subject is irrelevant.

> It's not a teasing for an intellectual challenge,
> just a constatation of a fact.


It is a fiction.

> Respectively this isArray


"This isArray"? Not the previous one?

> is absolutely rubust


So there can be no object for which - isArray(obj) - (where - isArray -
is your new version rather than the previous version that reported -
true - for the object I already posted) returns true?

One of the consequences of your basing your conception of javascript on
your ludicrous fictions is that you end up making statements that are
easily demonstrated as false. This object:-

function AnObject(){
;
}
AnObject.prototype = {
length:{
valueOf:function(){
return 1;
},
toString:function(){
return '0';
}
}
};
var obj = new AnObject();

alert(('isArray(obj) = '+isArray(obj)));//alerts isArray(obj) = true

- returns - true - from your newest "absolutely robust" array test, even
though it is clearly not an array. It does so for precisely the same
reason as my previous object returned true from your previous -
isArray - test. And if you had bothered to test my previous object with
your previous test you may have seen the obvious truth that would have
suggested that you not label this test as any more "absolutely robust"
as your last easily fooled test.

> yet absolutely not needed with instanceof alive.


If you had understood my criticism of your use of - instanceof - in this
context you would be able to see why that would not help anyway.

Richard.


Reply With Quote
 
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
t-test: robust standard error ptv-sas@sociology.osu.edu Newsgroup comp.soft-sys.sas 0 10-08-2005 01:43 AM



All times are GMT. The time now is 11:33 PM.


Copyright ©2009

LinkBacks Enabled by vBSEO 3.3.0 RC2 © 2009, Crawlability, Inc.