3358

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 so I can loop over it without fear of an error.

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

12
  • 8
    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? Commented Jul 23, 2015 at 18:23
  • 185
    TL;DR - arr.constructor === Array is fastest. Commented Nov 23, 2015 at 22:37
  • 5
    jsben.ch/#/QgYAV - a benchmark for the most common ways Commented Oct 24, 2016 at 17:34
  • 57
    TL;DR - Array.isArray(arr) since ES5; and $.isArray(arr) in jQuery. Commented Dec 19, 2016 at 9:55
  • 9
    Just bear in mind that if you by any reason overwrite your constructor via prototype that arr.constructor === Array test will return false. Array.isArray(arr) still returns true though. Commented Feb 23, 2018 at 17:44

51 Answers 51

2068

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);

There's also the constructor which you can query directly:

if (somevar.constructor.name == "Array") {
    // do something
}

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

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

From @Bharath, convert a string to an array using ES6 for the question asked:

const convertStringToArray = (object) => {
   return (typeof object === 'string') ? Array(object) : object
}

Suppose:

let m = 'bla'
let n = ['bla','Meow']
let y = convertStringToArray(m)
let z = convertStringToArray(n)
console.log('check y: '+JSON.stringify(y)) . // check y: ['bla']
console.log('check y: '+JSON.stringify(z)) . // check y: ['bla','Meow']
Sign up to request clarification or add additional context in comments.

4 Comments

+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
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
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/…
Live in the modern world - Array.isArray(obj)
1613

In modern browsers you can do:

Array.isArray(obj)

(Supported by Chrome 5, Firefox 4.0, Internet Explorer 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.js 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

3 Comments

Here is a more complete list of browsers that support Array.isArray
@NobleUplift: instanceof Array fails if the array is from a different frame because every array from that different frame has a different Array constructor and prototype. For compatibility/security reasons, every frame has its own global environment, and this includes global objects. The Object global from one frame is different from the Object global from another. So too for Array globals. Axel Rauschmayer talks more about this.
Note that, as of 2022, this is very well supported (even back many browser versions): caniuse.com/?search=isArray And also now the fastest method: jsben.ch/QgYAV
1324

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

2 Comments

v instanceof Array will return false if v was created in another frame (v is instance of thatFrame.contentWindow.Array class).
To be specific: Array.isArray is defined as part of ECMAScript 5/Javascript 1.8.5.
307

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>

1 Comment

Just a note, jQuery uses the toString method internally: GitHub Source
111

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

function isArray(obj){
    return !!obj && obj.constructor === Array;
}

Comments

54

Imagine you have this array below:

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 (Internet Explorer 9+, Chrome 5+, Firefox 4+, Safari 5+, and Opera 10.5+)

Array.isArray(arr);

jQuery:

$.isArray(arr);

Angular:

angular.isArray(arr);

Underscore.js and Lodash:

_.isArray(arr);

Comments

36

Array.isArray works fast, but it isn't supported by all versions of browsers.

So you could make an exception for others and use a universal method:

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

1 Comment

Array.isArray is pretty much supported by all modern browsers now caniuse.com/?search=isArray
33

A simple function to check this:

function isArray(object)
{
    return object.constructor === Array;
}

3 Comments

I'd reduce that down to one line return object.constructor === Array -- but are you sure that this will only return true for arrays?
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.
This fails badly if object is undefined or null.
28

You can use Array.isArray(). Here is a polyfill:

if (Array.isArray == null) {
  Array.isArray = (arr) => Object.prototype.toString.call(arr) === "[object Array]"
}

1 Comment

Can you elaborate a little bit? E.g., why is "Array.isArray" on both sides of the "="? "Array.isArray" is a method. What is the principle of operation? Please respond by editing (changing) your answer, not here in comments (without "Edit:", "Update:", or similar - the answer should appear as if it was written today).
21

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)

Comments

21

There's just one line solution for this question

x instanceof Array

where x is the variable it will return true if x is an array and false if it is not.

Comments

18

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
}

Comments

16

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

var myArray=[];

if(myArray instanceof Array)
{
....
}

1 Comment

A few people have already mentioned instanceof.. I think it fails under a few weird scenarios.
14

I do this in a very simple way. It works for me.

Array.prototype.isArray = true;

a=[]; b={};
a.isArray  // true
b.isArray  // (undefined -> false)

2 Comments

fooled by {isArray:true}
JSON.parse(someDataFromElsewhere).items.isArray could return true (depending on the data) and break your code.
13

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

1 Comment

constructor is not available in ES5
13

The best practice is to compare it using constructor, something like this

if(some_variable.constructor === Array){
  // do something
}

You can use other methods too, like typeOf, converting it to a string and then comparing, but comparing it with dataType is always a better approach.

Comments

12

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).

Comments

12

I know, that people are looking for some kind of raw JavaScript approach. But if you want think less about it, take a look at Underscore.js' isArray:

_.isArray(object)

It returns true if object is an Array.

(function(){ return _.isArray(arguments); })();
=> false
_.isArray([1,2,3]);
=> true

1 Comment

"Unless another tag for a framework/library is also included, a pure JavaScript answer is expected."
6

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

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 */};

Comments

5

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;
}

1 Comment

Yeah... that'd work for this scenario, but not in general. Ended up using varargs anyway. :)
5

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.

7 Comments

its not better in terms of performance anymore, at least on FF30 on Ubuntu 64-bit
fooled by wat = {array_: true} objects.
@Bergi: Yes, that should be obvious. If you're setting obj.array_ = true, then you're only fooling yourself.
@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.
@namuol: Also, this approach would require that all involved parties (including used libraries) can agree that .array_ is used for tagging arrays. That's really not the case here, .array can mean anything. You should at least use a descriptive string, and signal inappropriateness of arbitrary use, e.g. with .__isArray = true.
|
5

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.

Comments

5

The following could be used if you know that your object doesn't have a concat method.

var arr = [];
if (typeof arr.concat === 'function') {
    console.log("It's an array");
}

1 Comment

This is a good trick, but could be overridden... but most of the times should get the result
5
var a = [], b = {};

console.log(a.constructor.name == "Array");
console.log(b.constructor.name == "Object");

1 Comment

Hi, thanks for your answer. Code only answers tend to be overlooked, would you mind adding some explanation to your code?
5

There is a nice example in Stoyan Stefanov's book JavaScript Patterns which is supposed to handle all possible problems as well as use the 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 its method $.isArray().

1 Comment

+1: why not just a simple if(!Array.isArray) {... ?
5

The easiest and fastest way to check if an Object is an Array or not.

var arr = [];
arr.constructor.name === 'Array'  // Returns true;

or

arr.constructor === Array // Returns true;

Or you can make a utility function:

const isArray = (obj) => !!obj && obj.constructor === Array;

Usage:

isArray(arr); // Returns true

Comments

5

You could use the isArray method, but I would prefer to check with:

Object.getPrototypeOf(yourvariable) === Array.prototype

3 Comments

Why would you prefer this?
@mpen Object.getPrototypeOf(yourvariable) it returns prototype of an Array object. And The code is fastest and safe to rely on.
It's easy to foil: pastebin.com/MP8d5bCE Also, do you have performance tests to back up your "fastest" claim?
4
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))

1 Comment

An explanation would be in order. Please respond by editing (changing) your answer, not here in comments (without "Edit:", "Update:", or similar - the answer should appear as if it was written today).
4

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

Comments

4

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.