Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm trying to write a function that either accepts a list of strings, or a single string. If it's a string, then I want to convert it to an array with just the one item. Then I can loop over it without fear of an error.

So how do I check if the variable is an array?

share|improve this question

18 Answers

up vote 299 down vote accepted

The method given in the ECMAScript standard to find the class of Object is to use the toString method from Object.prototype.

if( Object.prototype.toString.call( someVar ) === '[object Array]' ) {
    alert( 'Array!' );
}

Or you could use typeof to test if it is a String:

if( typeof someVar === 'string' ) {
    someVar = [ someVar ];
}

Or if you're not concerned about performance, you could just do a concat to a new empty Array.

someVar = [].concat( someVar );

EDIT: Check out a thorough treatment from @T.J. Crowder's blog, as posted in his comment below.

share|improve this answer
17  
+1 Yup, toString is one of the ways to go. I do a bit of a roundup here: blog.niftysnippets.org/2010/09/say-what.html – T.J. Crowder Jan 23 '11 at 18:57
12  
Should mention jQuery's isArray. – Martin Konicek May 29 '12 at 16:42
1  
typeof new String('beans') > 'object' – Ben Aug 14 '12 at 16:11
12  
Wow, the concat one is elegant. – Camilo Martin Sep 10 '12 at 3:46
1  
If you don't want to type "[object Array]" use Object.prototype.toString.call( someVar ) === Object.prototype.toString.call( [] ) or make a convenience function to get type if you don't want to type Object.prototype.toString.call – Pramod Mar 15 at 6:15
show 4 more comments

I would first check if your implementation supports isArray:

if (Array.isArray)
    return Array.isArray(v);

You could also try using the instanceof operator

v instanceof Array
share|improve this answer
9  
+1 for instanceof Array. Simplest AFAICT – Tom Auger Nov 4 '11 at 1:14
33  
v instanceof Array will return false if v was created in another frame (v is instance of thatFrame.contentWindow.Array class). – pepkin88 Jan 3 '12 at 2:08
2  
instanceOf fails if array is decared as var a =[], – Jinu J D Jul 4 '12 at 5:04
6  
@JinuJD - I'm not sure what you're doing but I tested this in Firefox and IE and it still works. – ChaosPandion Jul 4 '12 at 5:21
6  
To be specific: Array.isArray is defined as part of ECMAScript 5/Javascript 1.8.5. – jevon Oct 23 '12 at 5:38
show 1 more comment

jQuery also offers an isArray method:

var a = ["A", "AA", "AAA"];

if($.isArray(a)) {
    alert("a is an array!");
} else {
    alert("a is not an array!");
}
share|improve this answer
6  
As a reference: api.jquery.com/jQuery.isArray – Akseli Palén May 8 '12 at 22:46

You can try this approach: https://waybackassets.bk21.net/20100424091244/http://www.ajaxdr.com/code/javascript-version-of-phps-is_array-function/

EDIT: also, if you are already using JQuery in your project, you can use its function $.isArray().

share|improve this answer
1  
Nice find with the jQuery route - few of us really explore the wealth of its less frequently used functions! – Dav Jun 28 '11 at 3:33
+1 Good find! Didn't know there was a jQuery isArray, this would have been useful quite some time ago – William Isted Jun 7 '12 at 13:54
That link is dead. – Mathieu M-Gosselin Jun 14 '12 at 0:46
Thanks @Mathieu, I replaced it with an archived copy. – André Paramés Jun 14 '12 at 11:06

Array.isArray works fast, but it isn't supported by all versions of browsers. So you could make an exception for others and use universal method:

    Utils = {};    
    Utils.isArray = ('isArray' in Array) ? 
        Array.isArray : 
        function (value) {
            return Object.prototype.toString.call(value) === '[object Array]';
        }
share|improve this answer
You might like to add an explanation of the code to make it easier to understand for other users, but otherwise - nice. +1 – Jeff Dec 10 '12 at 23:18
1  
You need to get the .toString() method from Object.prototype. Right now you're using the window.toString(), which isn't the same. – the system Feb 15 at 18:00
You are right. window.toString do the same as Object.prototype.toString just in Chrome. – CruorVult Feb 18 at 11:17
wow ('isArray' in Array). Never saw it before. thks – Ivan Ferrer Villa Mar 3 at 21:16

Simple function to check this:

function isArray(object)
{
    if (object.constructor === Array) return true;
    else return false;
}
share|improve this answer
4  
I'd reduce that down to one line return object.constructor === Array -- but are you sure that this will only return true for arrays? – Mark Sep 4 '12 at 18:39
Good point Mark, I didn't think of that. – MidnightTortoise Sep 4 '12 at 18:44
1  
Can do that with all boolean expressions. Drives me nuts when I see if(x) return true; else return false :-) Even if it's backwards, you should negate the expression. – Mark Sep 4 '12 at 18:52
Oh, it does indeed only return true for arrays, as far as I have found. var array_1 = new Array();//isArray(array_1) returns true var array_2 = [];//isArray(array_2) returns true It does not return true for array-like objects, such as those returned by getElementsByTagName, however. – MidnightTortoise Sep 4 '12 at 18:56
Thanks Mark, I shall remember that in future...and here was me thinking I was being clever! – MidnightTortoise Sep 4 '12 at 19:07
show 2 more comments

As MDN says in here:

use Array.isArray or Object.prototype.toString.call to differentiate regular objects from arrays

Like this:

  • Object.prototype.toString.call(arr) === '[object Array]', or

  • Array.isArray(arr)

share|improve this answer

You can check the type of your variable whether it is an array with;

var myArray=[];

if(myArray instanceof Array)
{
....
}
share|improve this answer
A few people have already mentioned instanceof.. I think it fails under a few weird scenarios. – Mark Jan 15 at 16:30

I would make a function to test the type of object you are dealing with...

function whatAmI(me){ return Object.prototype.toString.call(me).split(/\W/)[2]; }

// tests
console.log(
    whatAmI(["aiming","@"]),
    whatAmI({living:4,breathing:4}),
    whatAmI(function(ing){ return ing+" to the global window" }),
    whatAmI("going to do with you?")
);

// output: Array Object Function String

then you can write a simple if statement...

if(whatAmI(myVar) === "Array"){
    // do array stuff
} else { // could also check `if(whatAmI(myVar) === "String")` here to be sure
    // do string stuff
}
share|improve this answer

Here's my lazy-man approach:

if (Array.prototype.array_ === undefined) {
  Array.prototype.array_ = true;
}

// ...

var test = [],
    wat = {};

console.log(test.array_ === true); // true
console.log(wat.array_ === true);  // false

I know it's sacrilege to "mess with" the prototype, but it appears to perform significantly better than the recommended toString method.

Note: A pitfall of this approach is that it wont work across iframe boundaries, but for my use case this is not an issue.

share|improve this answer

If the only two kinds of values that could be passed to this function are a string or an array of strings, keep it simple and use a typeof check for the string possibility:

function someFunc(arg) {
    var arr = (typeof arg == "string") ? [arg] : arg;
}
share|improve this answer
Yeah... that'd work for this scenario, but not in general. Ended up using varargs anyway. :) – Mark Jan 23 '11 at 20:01

The best solution I've seen is a cross-browser replacement for typeof. Check Angus Croll's solution here.

The TL;DR version is below, but the article is a great discussion of the issue so you should read it if you have time.

Object.toType = function(obj) {
    return ({}).toString.call(obj).match(/\s([a-z|A-Z]+)/)[1].toLowerCase();
}
// ... and usage:
Object.toType([1,2,3]); //"array" (all browsers)

// or to test...
var shouldBeAnArray = [1,2,3];
if(Object.toType(shouldBeAnArray) === 'array'){/* do stuff */};
share|improve this answer

I know, that people are looking for some kind of raw javascript approach. But if you want think less about, take a look here: http://documentcloud.github.com/underscore/#isArray

isArray_.isArray(object) 

Returns true if object is an Array.

(function(){ return _.isArray(arguments); })();
=> false
_.isArray([1,2,3]);
=> true
share|improve this answer
1  
I like the example you chose. Those pesky arguments :-) – Mark Jan 11 at 16:44
yeah, thank you :) – Eugene Jan 22 at 6:45

Dojo Toolkit has deprecated its isArray() function and now recommends using simply:

val instanceof Array
share|improve this answer

Since I don't like any Object.prototype-calls, I searched for another solution. Especially because the solutions of ChaosPandion won't always work, and the solution of MidnightTortoise with isArray() doesn't work with arrays coming from the DOM (like getElementsByTagName). And finally I found an easy and cross-browser solution, which probably also would have worked with Netscape 4. ;)

It's just these 4 lines (checking any object h):

function isArray(h){
    if((h.length!=undefined&&h[0]!=undefined)||(h.length===0&&h[0]===undefined)){
        return true;
    }
    else{ return false; }
}

I already tested these arrays (all return true):

1) array=d.getElementsByName('some_element'); //'some_element' can be a real or unreal element
2) array=[];
3) array=[10];
4) array=new Array();
5) array=new Array();
   array.push("whatever");

Can anybody confirm that this works for all cases? Or does anybody find a case where my solution don't work?

share|improve this answer
Absolutely. As a trivial example: jsfiddle.net/mnbayazit/fDwwV – Mark Feb 12 at 16:36
1  
Too many false positives. isArray(function(){}); // true, isArray("foo"); // true, isArray({length:0}); // true – the system Feb 15 at 18:05
1  
...and a NodeList isn't an Array anyway. – the system Feb 15 at 18:06
Thanks for sharing your test results. This is getting my a lot more insight how Javascript works internally. – Marcus Feb 15 at 20:52
The usage of charAt just vanished everywhere out of my code. ;) – Marcus Feb 15 at 21:14
show 2 more comments
A = [1,2,3]
console.log(A.map==[].map)

In search for shortest version here is what I got so far.

Note, there is no perfect function that will always detect all possible combinations. It is better to know all abilities and limitations of your tools than expect a magic tool.

share|improve this answer
slight derivation of mine A.map !== undefined but yeah, that could be slippy road in the world of monkey patchers ;) – dmi3y Mar 31 at 2:47

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/isArray

Array.isArray = Array.isArray || function (vArg) {
    return Object.prototype.toString.call(vArg) === "[object Array]";
};
share|improve this answer

You could try checking if the object in question has an array method as one of its methods such as push or slice. This doesn't guarantee absolutely that it is an array, but objects that have methods with those names are probably going to be arrays.

var a = [];
var b = {};

if ((a.slice) && (a.slice === function))
{
    alert ('A is an array');
}
else
{
    alert ('A is not an array');
}

if ((b.slice) && (b.slice === function))
{
    alert ('B is an array');
}
else
{
    alert ('B is not an array');
}

Beware, however, this method can be defeated if you have a non-array object that happens to implement a slice methods.

b.slice = function (){}

if ((b.slice) && (b.slice === function))
{
    alert ('B is an array');
}
else
{
    alert ('B is not an array');
}
share|improve this answer
7  
Because OP is hoping to differentiate between a String and Array, this will fail because String also has a native .slice() method. – user113716 Jan 23 '11 at 19:22

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.