Join the Stack Overflow Community
Stack Overflow is a community of 6.6 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

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?


I've rounded up the various solutions below and created a jsperf test.

share|improve this question
5  
I thought you meant to 'check if object is an array', but you want to check if 'object is an array of strings or a single string' specifically. Not sure if you see it? Or is it just me? I was thinking of something more like this... am I the one missing something here? – rr1g0 Jul 23 '15 at 18:23
52  
TL;DR - arr.constructor === Array is fastest. – Neta Nov 23 '15 at 22:37
1  
@vsync There's a hyperlink. You guys can run it as much as you like. The screenshot is there just for people that are too lazy to click. – mpen Dec 22 '15 at 18:38
2  
jsben.ch/#/QgYAV - a benchmark for the most common ways – EscapeNetscape Oct 24 '16 at 17:34
1  
TL;DR - Array.isArray(arr) since ES5; and $.isArray(arr) in jQuery. – Ondra Žižka Dec 19 '16 at 9:55

32 Answers 32

up vote 1551 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.

EDIT 2: Check out this benchmark to get an idea which method performs better: http://jsben.ch/#/QgYAV

share|improve this answer
55  
+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
96  
Should mention jQuery's isArray. – Martin Konicek May 29 '12 at 16:42
14  
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 '13 at 6:15
12  
Wow. The concat method is the one diseased rat. I'd give a +2 but that's not allowed – Dark Star1 Apr 9 '13 at 9:00
5  
I use the vanilla Array.isArray which works in 'modern browsers' (that is, IE9+ and everyone else). And for old browser support use the shim from MDN developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… – David Gilbertson Oct 11 '13 at 4:40

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
68  
+1 for instanceof Array. Simplest AFAICT – Tom Auger Nov 4 '11 at 1:14
100  
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
30  
@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
35  
To be specific: Array.isArray is defined as part of ECMAScript 5/Javascript 1.8.5. – jevon Oct 23 '12 at 5:38
5  
Really simple and neat solution BUT isArray is not compatible with some older browsers (e.x. IE7 and IE8). Source: kangax.github.io/es5-compat-table/# – Wookie88 Jul 1 '13 at 10:16

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!");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

share|improve this answer
15  
As a reference: api.jquery.com/jQuery.isArray – Akseli Palén May 8 '12 at 22:46
22  
Just a note, jQuery uses the toString method internally: GitHub Source – Jacob Squires Apr 17 '14 at 1:25
4  
@JacobSquires it depends. I just tested here, latest jQuery on Chrome - $.isArray === Array.isArray is returning true. – Renan Oct 22 '14 at 14:12
2  
@Renan: This is the good thing about using jQuery. It usually uses the most modern and best method to do it, and you don't have to do all the feature checking yourself to know what to use. – awe Dec 2 '15 at 9:55
    
jQuery is using Array.isArray behind the scenes: github.com/jquery/jquery/blob/master/src/core.js#L211 – Sergiu Apr 24 '16 at 9:16

In modern browsers you can do

Array.isArray(obj)

(Supported by Chrome 5, Firefox 4.0, IE 9, Opera 10.5 and Safari 5)

For backward compatibility you can add the following

# only implement if no native implementation is available
if (typeof Array.isArray === 'undefined') {
  Array.isArray = function(obj) {
    return Object.prototype.toString.call(obj) === '[object Array]';
  }
};

If you use jQuery you can use jQuery.isArray(obj) or $.isArray(obj). If you use underscore you can use _.isArray(obj)

If you don't need to detect arrays created in different frames you can also just use instanceof

obj instanceof Array
share|improve this answer
12  
Array.isArray(obj) also works in nodejs. – neoneye May 15 '14 at 10:48
3  
Here is a more complete list of browsers that support Array.isArray – lightswitch05 Dec 17 '14 at 18:51

This is the fastest among all methods (all browsers supported):

function isArray(obj){
    return !!obj && Array === obj.constructor;
}
share|improve this answer
1  
You're right, that is the fastest according to the tests I included in the question. – mpen Dec 6 '15 at 21:59
3  
Are there any downsides to using this method? It seems much more simple and effective than the accepted, top answer. – David Meza Jan 26 '16 at 18:35
    
@shinobi - just curious (and i've seen this often) - why do you phrase the condition if (obj && Array === obj.constructor) as opposed to if (obj && obj.constructor === Array) ? Is it a lost in translation to english, then to code thing? eg, english speakers generally tend to ask "does the object exist, and does it's constructor come from the array class?", so the code flow when reading it is more logical. or is there some technical reason? – unsynchronized Jun 26 '16 at 1:54
    
function object_type(o){var t = typeof(o);return ((t==="object") && (o.constructor===Array)) ? "array" : t;} /*allows you to */ switch(object_type(o)){ case 'array': break; case 'object' : o.dosomething();} – unsynchronized Jun 26 '16 at 6:10
3  
@shinobi all good. i suppose it might be a hangover from a safe c habit - if you accidentally use = instead ==, it would not compile as its not an assignable variable. – unsynchronized Jun 26 '16 at 6:35

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
1  
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
3  
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 '13 at 18:00
    
You are right. window.toString do the same as Object.prototype.toString just in Chrome. – CruorVult Feb 18 '13 at 11:17
5  
wow ('isArray' in Array). Never saw it before. thks – Ivan Ferrer Villa Mar 3 '13 at 21:16
    
isArray is not fast at all. It is the slowest method. – JemiloII Dec 12 '14 at 16:01

Simple function to check this:

function isArray(object)
{
    if (object.constructor === Array) return true;
    else return false;
}
share|improve this answer
13  
I'd reduce that down to one line return object.constructor === Array -- but are you sure that this will only return true for arrays? – mpen Sep 4 '12 at 18:39
6  
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. – mpen Sep 4 '12 at 18:52
3  
The reason this doesn't return true for getElementsByTagName, is because the result of that function is actually an HTMLCollection and not an array. – Yuval A. Dec 4 '14 at 17:35
4  
This fails badly if object is undefined or null. – John Henckel Mar 20 '15 at 15:58
1  
@JohnHenckel See my answer stackoverflow.com/a/29400289/34806 it takes into account both your concern as well as the very first comment, all on one line – George Jempty Apr 1 '15 at 20:37

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
2  
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
2  
In your approach all objects which contains property push will be array: is_array({push: true});//true – CruorVult Dec 6 '13 at 10:44

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
1  
A few people have already mentioned instanceof.. I think it fails under a few weird scenarios. – mpen Jan 15 '13 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

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

I do this in a very simple way. Works for me. Any drawbacks?

Array.prototype.isArray = true;

a=[]; b={};
a.isArray  // true
b.isArray  // (undefined -> false)
share|improve this answer
4  
fooled by {isArray:true} – Bergi Aug 7 '15 at 7:17
    
JSON.parse(someDataFromElsewhere).items.isArray could return true (depending on the data) and break your code. – Roy Tinker Dec 19 '16 at 20:52

This is my attempt to improve on this answer taking into account the comments:

var isArray = myArray && myArray.constructor === Array;

It gets rid of the if/else, and accounts for the possibility of the array being null or undefined

share|improve this answer

I have updated the jsperf fiddle with two alternative methods as well as error checking.

It turns out that the method defining a constant value in the 'Object' and 'Array' prototypes is faster than any of the other methods. It is a somewhat surprising result.

/* Initialisation */
Object.prototype.isArray = function() {
  return false;
};
Array.prototype.isArray = function() {
  return true;
};
Object.prototype._isArray = false;
Array.prototype._isArray = true;

var arr = ["1", "2"];
var noarr = "1";

/* Method 1 (function) */
if (arr.isArray()) document.write("arr is an array according to function<br/>");
if (!noarr.isArray()) document.write("noarr is not an array according to function<br/>");
/* Method 2 (value) - **** FASTEST ***** */
if (arr._isArray) document.write("arr is an array according to member value<br/>");
if (!noarr._isArray) document.write("noarr is not an array according to member value<br/>");

These two methods do not work if the variable takes the undefined value, but they do work if you are certain that they have a value. With regards to checking with performance in mind if a value is an array or a single value, the second method looks like a valid fast method. It is slightly faster than 'instanceof' on Chrome, twice as fast as the second best method in Internet Explorer, Opera and Safari (on my machine).

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://underscorejs.org/#isArray

_.isArray(object) 

Returns true if object is an Array.

(function(){ return _.isArray(arguments); })();
=> false
_.isArray([1,2,3]);
=> true
share|improve this answer
4  
"Unless another tag for a framework/library is also included, a pure JavaScript answer is expected." – Gothdo Jan 9 '16 at 21:53

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

Here's my lazy 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
    
Does work on IE8 32bit and 64bit. – datico Oct 10 '13 at 0:32
    
its not better in terms of performance anymore, at least on FF30 on Ubuntu 64-bit – test30 Jul 21 '14 at 9:40
2  
fooled by wat = {array_: true} objects. – Bergi Aug 7 '15 at 7:18
    
@Bergi: Yes, that should be obvious. If you're setting obj.array_ = true, then you're only fooling yourself. – namuol Aug 7 '15 at 23:56
    
@namuol: I'm not necessarily fooling myself. Often enough objects are used as dictionaries. Think of a cache object to memoize search results which uses the search strings as property keys. What if a user searches for array_? Does your object become an array because of that? It's just a bug. – Bergi Aug 8 '15 at 16:15

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. :) – mpen Jan 23 '11 at 20:01
function isArray(value) {
    if (value) {
        if (typeof value === 'object') {
            return (Object.prototype.toString.call(value) == '[object Array]')
        }
    }
    return false;
}

var ar = ["ff","tt"]
alert(isArray(ar))
share|improve this answer

There is a nice example in Stoyan Stefanov's book JavaScript Patterns which suppose to handle all possible problems as well as utilize ECMAScript 5 method Array.isArray().

So here it is:

if (typeof Array.isArray === "undefined") {
    Array.isArray = function (arg) {
        return Object.prototype.toString.call(arg) === "[object Array]";
    };
}

By the way, if you are using jQuery, you can use it's method $.isArray()

share|improve this answer
2  
+1: why not just a simple if(!Array.isArray) {... ? – Marco Demaio Feb 18 '14 at 14:49

A simple function for testing if an input value is an array is the following:

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

This works cross browser, and with older browsers. This is pulled from T.J. Crowders' blog post

share|improve this answer
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 '13 at 2:47
    
FYI: This doesn't work across iFrames (stackoverflow.com/questions/460256/…) – WiredPrairie Oct 27 '13 at 20:48

This function will turn almost anything into an array:

function arr(x) {
    if(x === null || x === undefined) {
        return [];
    }
    if(Array.isArray(x)) {
        return x;
    }
    if(isString(x) || isNumber(x)) {
        return [x];
    }
    if(x[Symbol.iterator] !== undefined || x.length !== undefined) {
        return Array.from(x);
    }
    return [x];
}

function isString(x) {
    return Object.prototype.toString.call(x) === "[object String]"
}

function isNumber(x) {
    return Object.prototype.toString.call(x) === "[object Number]"
}

It uses some newer browser features so you may want to polyfill this for maximum support.

Examples:

> arr(null);
[]
> arr(undefined)
[]
> arr(3.14)
[ 3.14 ]
> arr(1/0)
[ Infinity ]
> gen = function*() { yield 1; yield 2; yield 3; }
[Function: gen]
> arr(gen())
[ 1, 2, 3 ]
> arr([4,5,6])
[ 4, 5, 6 ]
> arr("foo")
[ 'foo' ]

N.B. strings will be converted into an array with a single element instead of an array of chars. Delete the isString check if you would prefer it the other way around.

I've used Array.isArray here because it's the most robust and also simplest.

share|improve this answer

imagine you have this array:

var arr = [1,2,3,4,5];

Javascript (new and older browsers):

function isArray(arr) {
    return arr.constructor.toString().indexOf("Array") > -1;
}

or

function isArray(arr) {
    return arr instanceof Array;
}

or

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

then call it like this:

isArray(arr);

Javascript (IE9+, Ch5+, FF4+, Saf5+, Opera10.5+)

Array.isArray(arr);

jQuery:

$.isArray(arr);

Angular:

angular.isArray(arr);

Underscore and Lodash:

_.isArray(arr);
share|improve this answer

I know this is an old question but here is a solution that I came up with and have been using for my projects...

function isArray (o) {
    return typeof o === "object" && o.length !== undefined;
}

isArray({}); // false
isArray(1); // false
isArray("str"); // false
isArray(function(){}); // false

isArray([]); // true

The only pitfall is that it will give a false positive if your object happens to have a length property:

isArray({length:0}); // true

If you are okay with that drawback and know your pure objects won't have that property, it's a clean solution and should be faster than the Object.prototype.toString.call method.

share|improve this answer
    
isArray( new String() ); returns true – László Kardinál Feb 24 '16 at 15:19
    
Yes, I noted that as a pitfall in my comments below the examples: "The only pitfall is that it will give a false positive if your object happens to have a length property" – Sensei_Shoh Feb 24 '16 at 18:18
var is_array = function (value) {
   return value &&
     typeof value === 'object' &&
     typeof value.length === 'number' &&
     typeof value.splice === 'function' &&
    !(value.propertyIsEnumerable('length'));
};

This function has been taken from "JS the good parts" book, works perfect for me.

share|improve this answer
    
var object = {splice: function(){}}; Object.defineProperty(object, "length", {value: 1, enumerable: false}); console.log(is_array(object)); – Gothdo Jan 9 '16 at 22:02

You can try this:

var arr = []; (or) arr = new Array();
var obj = {}; (or) arr = new Object();

arr.constructor.prototype.hasOwnProperty('push') //true

obj.constructor.prototype.hasOwnProperty('push') // false
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 – mpen Feb 12 '13 at 16:36
2  
Too many false positives. isArray(function(){}); // true, isArray("foo"); // true, isArray({length:0}); // true – the system Feb 15 '13 at 18:05
2  
...and a NodeList isn't an Array anyway. – the system Feb 15 '13 at 18:06
    
Thanks for sharing your test results. This is getting my a lot more insight how Javascript works internally. – Marcus Feb 15 '13 at 20:52
    
The usage of charAt just vanished everywhere out of my code. ;) – Marcus Feb 15 '13 at 21:14

You can use this function to get data type.

var myAr  = [1,2];

checkType(myAr);

function checkType(data){
  if(typeof data ==='object'){
    if(Object.prototype.toString.call(data).indexOf('Array')!==(-1)){
      return 'array';
    } else{
      return 'object';
    }
  } else {
    return typeof data;
  }
}

if(checkType(myAr) === 'array'){console.log('yes, It is an array')};
share|improve this answer
    
All the op asked for was a simple efficient check. – Kermit_ice_tea Jul 27 '16 at 20:04

protected by durron597 Sep 23 '15 at 18:27

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

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