6

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?

Gumbo
  • 643,351
  • 109
  • 780
  • 844
Artilheiro
  • 4,005
  • 10
  • 36
  • 34
  • 3
    You're making your life harder than it needs to be. I would consider it better style if the function always returns an array. – Miles Jul 30 '09 at 19:01

5 Answers5

16

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:

Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
  • Perfect! I am using jQuery so I'll just use that. The article helped too. – Artilheiro Jul 29 '09 at 20:55
  • in modern browsers we have Array.isArray function, so better write smth like if !Array.isArray { ... here goes the definition ...} – shabunc Jul 26 '11 at 09:20
3
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
  • 83,552
  • 10
  • 84
  • 84
  • 1
    see https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Operators/Special_Operators/instanceof_Operator – VolkerK Jul 29 '09 at 20:32
  • 5
    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 Jul 29 '09 at 20:35
  • a detailed post about using this method: http://thinkweb2.com/projects/prototype/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/ – Christian C. Salvadó Jul 29 '09 at 20:43
  • 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 Jul 29 '09 at 20:51
  • 2
    And this won't work for different global contexts; like an object from within an iframe... – James Jul 29 '09 at 21:04
  • Additionally, the Array object can be overwritten with a custom object. Just FYI. – Josh Stodola Jul 29 '09 at 21:29
  • 1
    @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 Jul 29 '09 at 21:38
  • 1
    @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 Jul 29 '09 at 21:46
  • @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 Jul 30 '09 at 22:12
  • @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 Jul 31 '09 at 02:14
  • 1
    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 Dec 05 '09 at 05:31
  • @CrescentFresh iframes have too many problems, and too little benefits now that we have AJAX and the browser's landscape is brighter. I think that if something doesn't work with iframes, it's ok. – Camilo Martin Sep 23 '12 at 08:22
2

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; }
}
Gordon Gustafson
  • 40,133
  • 25
  • 115
  • 157
2

As of ES5 there is isArray.

Array.isArray([])  // true
IliasT
  • 3,973
  • 1
  • 24
  • 26
0

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';
}
dankuck
  • 198
  • 1
  • 1
  • 11