views:

287

answers:

4

Say I have a function like so:

function foo(bar) {
    if (bar > 1) {
       return [1,2,3];
    } else {
       return 1;
    }
}

And say I call foo(1), how do I know it returns an array or not?

+3  A: 
if(foo(1) instanceof Array)
    // You have an Array
else
    // You don't

Update: I have to respond to the comments made below, because people are still claiming that this won't work without trying it for themselves...

For some other objects this technique does not work (e.g. "" instanceof String == false), but this works for Array. I tested it in IE6, IE8, FF, Chrome and Safari. Try it and see for yourself before commenting below.

Prestaul
see https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Operators/Special_Operators/instanceof_Operator
VolkerK
That will *only* work, if you declare an array via `new Array()`, not with the `[]` shorthand. See the section 'Description' under the above URL.
Boldewyn
a detailed post about using this method: http://thinkweb2.com/projects/prototype/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
CMS
The solution seems to work in Chrome, need to check other browsers. However, I did ready somewhere else that it does not work with [].
Artilheiro
And this won't work for different global contexts; like an object from within an iframe...
J-P
Additionally, the Array object can be overwritten with a custom object. Just FYI.
Josh Stodola
@Boldewyn, that is not true. It is true for some other objects (e.g. "" instanceof String == false), but this works for Array. Try it and see for yourself.
Prestaul
@Josh Stodola, so can Object.prototype.toString. You can overwrite nearly everything in js, but there are some assumptions you have to make in order to answer a question.
Prestaul
doesn't work if the array is declared with []
Dani Cricco
@Dani, did you try? I just did and it works in IE6, 8, FF, Chrome and Safari... Read what I wrote to Boldewyn and Josh before you guys keep claiming it doesn't work!
Prestaul
the main issue, as J-P already stated, is with frames.
Jimmy
@Jimmy, is that the main issue? Did the author specify that the solution needed to work across frames? Did you notice that three people commented (incorrectly) that [] instanceof Array wouldn't work? What percentage of javascript would you say works across frames?
Prestaul
Yes, `[] instanceof Array` is `true` in every browser, not sure why everyone went on a commenting tirade re that one. Also, indeed `Object.prototype.toString = function(){ return 'foo' }` can cause the accepted answer to fail. The *only* problem with `instanceof ` is with cross-frame instances. No method is bullet-proof it seems.
Crescent Fresh
+9  A: 

I use this function:

function isArray(obj) {
  return Object.prototype.toString.call(obj) === '[object Array]';
}

Is the way that jQuery.isArray is implemented.

Check this article:

CMS
Perfect! I am using jQuery so I'll just use that. The article helped too.
Artilheiro
A: 

To make your solution more general, you may not care whether it is actually an Array object. For example, document.getElementsByName() returns an object that "acts like" an array. "Array compliance" can be assumed if the object has a "length" property.

function is_array_compliant(obj){
    return obj && typeof obj.length != 'undefined';
}
dan
Strings have a "length" property, too.
Robert L
That's true. So, you should also check that:typeof obj == "object"
dan
+1  A: 

Here is one very reliable way, take from Javascript: the good parts, published by O'Reilly:

if (my_value && typeof my_value === 'object' &&  typeof my_value.length === 'number' &&
!(my_value.propertyIsEnumerable('length')) { // my_value is truly an array! }

I would suggest wrapping it in your own function:

function isarray(my_value) {

    if (my_value && typeof my_value === 'object' &&  typeof my_value.length === 'number' &&
        !(my_value.propertyIsEnumerable('length')) 
         { return true; }
    else { return false; }
}
CrazyJugglerDrummer