![]() |
Robust isArray() ?
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? -- Matt Kruse http://www.JavascriptToolbox.com http://www.AjaxToolbox.com |
Re: Robust isArray() ?
Matt Kruse wrote: [snip] > // 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; > } [/snip] Could you could do a toString instead on the constructor, and check that? > // As a last resort, let's see if index [0] is defined > return (o.length==0 || defined(o[0])); > }; Would that catch NodeLists and HTMLCollections? I.e. are you looking for objects that are genuine JavaScript "Arrays" or objects which have a certain minimum interface, like "length" and "[]" index access. I note also that "arguments" in IE has "Object" as its constructor, but "Array" in Opera or Firefox I think. Regards |
Re: Robust isArray() ?
Julian Turner wrote:
> Could you could do a toString instead on the constructor, and check > that? I don't think so, because that can vary between browsers and doesn't return just a single string like "Array". >> // As a last resort, let's see if index [0] is defined >> return (o.length==0 || defined(o[0])); >> }; > Would that catch NodeLists and HTMLCollections? Yup. > I.e. are you looking for objects that are genuine JavaScript "Arrays" > or objects which have a certain minimum interface, like "length" and > "[]" index access. The latter. Something that must (or can) be iterated over, rather than interacted with directly. > I note also that "arguments" in IE has "Object" as its constructor, > but "Array" in Opera or Firefox I think. The provided functions works in both cases. I guess one thing I'm also looking for is something that is most certainly NOT an array, but returns true with the provided function. Then, depending on if the test case is practical or not, I can re-think it. I don't think a perfect solution exists. -- Matt Kruse http://www.JavascriptToolbox.com http://www.AjaxToolbox.com |
Re: Robust isArray() ?
In comp.lang.javascript message <els04h030rh@news4.newsguy.com>, Thu, 14
Dec 2006 11:03:11, Matt Kruse <newsgroups@mattkruse.com> wrote: > ... > // As a last resort, let's see if index [0] is defined > return (o.length==0 || defined(o[0])); If something with contents matching those of o = [,1] can get that far, the code will return false in IE6. But, on the principle of Feature Detection, rather than trying to see what it "*is*", should one not be testing whether it will *do* what one wants it to do? If there is, for example, no intention of using its (possible) .Sort method, then there should be no need to test for .sort - unless one believes in the Shibboleth Method. -- (c) John Stockton, Surrey, UK. ?@merlyn.demon.co.uk DOS 3.3, 6.20; WinXP. Web <URL:http://www.merlyn.demon.co.uk/> - FAQqish topics, acronyms & links. PAS EXE TXT ZIP via <URL:http://www.merlyn.demon.co.uk/programs/00index.htm> My DOS <URL:http://www.merlyn.demon.co.uk/batfiles.htm> - also batprogs.htm. |
Re: Robust isArray() ?
Matt Kruse wrote:
> I'm seeking the most robust and backwards-compatible (ie, no instanceof) > isArray function. How backwards do you have to go? JavaScript 1.0 didn't have arrays at all. function isArray(v) { return v && typeof v === 'object' && typeof v.length === 'number' && !(v.propertyIsEnumerable('length')); } It thinks that the arguments object is an array (which it ought to be (but isn't)). http://javascript.crockford.com/ |
Re: Robust isArray() ?
Dr J R Stockton wrote:
>> // As a last resort, let's see if index [0] is defined >> return (o.length==0 || defined(o[0])); > If something with contents matching those of o = [,1] can get that > far... It wouldn't. > But, on the principle of Feature Detection, rather than trying to see > what it "*is*", should one not be testing whether it will *do* what > one wants it to do? If there is, for example, no intention of using > its (possible) .Sort method, then there should be no need to test for > .sort - unless one believes in the Shibboleth Method. Please do tell how you would "feature detect" whether an object can be enumerated over using numeric indexes? I don't see any fool-proof way to do it, thereby requiring a more complex isArray function and inferring features rather than detecting them. -- Matt Kruse http://www.JavascriptToolbox.com http://www.AjaxToolbox.com |
Re: Robust isArray() ?
Douglas Crockford wrote:
> How backwards do you have to go? JavaScript 1.0 didn't have arrays at > all. Then it would be hard to detect them ;) > function isArray(v) { > return v && typeof v === 'object' && typeof v.length === 'number' > && !(v.propertyIsEnumerable('length')); > } How compatible is propertyIsEnumerable? > It thinks that the arguments object is an array (which it ought to be > (but isn't)). It behaves like one, so IMO it should return true. -- Matt Kruse http://www.JavascriptToolbox.com http://www.AjaxToolbox.com |
Re: Robust isArray() ?
Matt Kruse said the following on 12/14/2006 12:03 PM:
> 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? var myArray = new Array(); myArray[0] = "Its an array"; myArray[1] = "It really is an array!"; alert(isArray('myArray')) IE7: false Opera 9: false Firefox 2.0: false -- Randy Chance Favors The Prepared Mind comp.lang.javascript FAQ - http://jibbering.com/faq Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/ |
Re: Robust isArray() ?
Randy Webb said the following on 12/14/2006 11:05 PM:
> Matt Kruse said the following on 12/14/2006 12:03 PM: >> 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? > > var myArray = new Array(); > myArray[0] = "Its an array"; > myArray[1] = "It really is an array!"; > alert(isArray('myArray')) > > IE7: false > Opera 9: false > Firefox 2.0: false And now I know why after giving it some thought and thinking about it. I passed the name of the array rather than the array itself. Might be something to think about though. The possibility of passing the name instead of the array itself. -- Randy Chance Favors The Prepared Mind comp.lang.javascript FAQ - http://jibbering.com/faq Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/ |
Re: Robust isArray() ?
Matt Kruse wrote: > Julian Turner wrote: > > Could you could do a toString instead on the constructor, and check > > that? > > I don't think so, because that can vary between browsers and doesn't return > just a single string like "Array". I take your point. I think it has been noted before that the results of toString are implementation independent. However, as you are testing for a positive, it could be another String to the bow (if you will pardon the pun!). [snip] > > I note also that "arguments" in IE has "Object" as its constructor, > > but "Array" in Opera or Firefox I think. > > The provided functions works in both cases. Yes, it would, as you are testing for length etc. > I guess one thing I'm also looking for is something that is most certainly > NOT an array, but returns true with the provided function. Then, depending > on if the test case is practical or not, I can re-think it. I don't think a > perfect solution exists. Hmm, what about this. function falseArray() { this.length = 1; this[0] = "False first element"; } Can't think when you would encounter this though. Regards Julian |
| All times are GMT. The time now is 06:11 AM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.