By mpen


2011-01-23 18:53:04 8 Comments

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.

30 comments

@Atishay Jain 2019-02-09 20:12:14

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.

@underthecode 2019-02-04 19:29:19

Here's a code snippet that'll explain an important fact of arrays that should be known early on while learning JS (unlike me).

// this functions puts a string inside an array
var stringInsideArray = function(input) {
  if (typeof input === 'string') {
    return [input];
  }
  else if (Array.isArray(input)) {
    return input;
  } 
  else {
    throw new Error("Input is not a string!");
  }
}

var output = stringInsideArray('hello');
console.log('step one output: ', output); // ["hello"]

// use typeof method to verify output is an object
console.log('step two output: ', typeof output); // object

// use Array.isArray() method to verify output is an array
console.log('step three output: ', Array.isArray(output)); // true

Arrays, are in fact, objects.

Using the typeof operator, the output of stringInsideArray('hello') proves that ["hello"] is really an object. This baffled me for the longest time because I assumed that arrays would be a JavaScript data type...

There are only 7 JS data types and arrays are NOT one of them.

To answer your question, using the Array.isArray() method determines that the output is an array.

@mpen 2019-02-06 04:04:19

Just FYI, [].concat(string) is kind of a weird way of writing [string].

@underthecode 2019-02-06 06:38:37

@mpen thanks for letting me know. out of curiosity, how would you write this?

@mpen 2019-02-06 08:22:04

function toArray(x) { if(x === undefined) return []; if(Array.isArray(x)) return x; return [x]; } or possibly [...x] for the middle case depending on whether or not you expect a new array to be returned.

@underthecode 2019-02-06 12:49:32

@mpen your solution makes a lot more sense. updating my answer accordingly. thanks!

@mpen 2019-02-06 19:34:41

You're quietly suppressing numbers and other non-string inputs if you write it that way. If you only want to allow strings then you should throw an Error if they don't provide one. The scenario I had in mind would allow arrays of anything.

@underthecode 2019-02-07 06:01:24

when you say Error, something like this for the else statement? else { throw "Input is not a string!"; }

@mpen 2019-02-07 07:49:24

Yes, but you shouldn't throw bare strings. Try throw new Error("Input is not a string!") instead.

@underthecode 2019-02-07 13:02:28

thanks again for the code review/input.

@bitfishxyz 2018-12-13 07:16:46

there is a difference between checkout it's prototype and Array.isArray:

function isArray(obj){
    return Object.getPrototypeOf(obj) === Array.prototype
}

this function will directly check if an obj is an array

but for this Proxy object:

var arr = [1,2,3]

var proxy = new Proxy(arr,{})

console.log(Array.isArray(proxy)) // true

Array.isArray will take it as Array.

@mpen 2018-12-13 18:13:19

You seem to be implying that your isArray function won't return true for the Proxy, but that's not the case; they both return true for the Proxy (and unproxied arrays)

@hygull 2018-10-12 06:31:45

Other methods also exist to check but I prefer the following method as my best to check (as you can easily check types of other objects).

> a = [1, 2]
[ 1, 2 ]
>
> Object.prototype.toString.call(a).slice(8,).replace(/\]$/, '')
'Array'
>
> Object.prototype.toString.call([]).slice(8,-1) // best approach
'Array'

Explanation (with simple examples on Node REPL)»

> o = {'ok': 1}
{ ok: 1 }
> a = [1, 2]
[ 1, 2 ]
> typeof o
'object'
> typeof a
'object'
>
> Object.prototype.toString.call(o)
'[object Object]'
> Object.prototype.toString.call(a)
'[object Array]'
>

Object or Array »

> Object.prototype.toString.call(o).slice(8,).replace(/\]$/, '')
'Object'
>
> Object.prototype.toString.call(a).slice(8,).replace(/\]$/, '')
'Array'
>

Null or Undefined »

> Object.prototype.toString.call(undefined).slice(8,).replace(/\]$/, '')
'Undefined'
> Object.prototype.toString.call(null).slice(8,).replace(/\]$/, '')
'Null'
>

String »

> Object.prototype.toString.call('ok').slice(8,).replace(/\]$/, '')
'String'

Number »

> Object.prototype.toString.call(19).slice(8,).replace(/\]$/, '')
'Number'
> Object.prototype.toString.call(19.0).slice(8,).replace(/\]$/, '')
'Number'
> Object.prototype.toString.call(19.7).slice(8,).replace(/\]$/, '')
'Number'
>

I appreciate @mpen's suggestion to use -1 in place of regular expression as follows.

> Object.prototype.toString.call(12).slice(8,-1)
'Number'
>
> Object.prototype.toString.call(12.0).slice(8,-1)
'Number'
>
> Object.prototype.toString.call([]).slice(8,-1)
'Array'
> Object.prototype.toString.call({}).slice(8,-1)
'Object'
>
> Object.prototype.toString.call('').slice(8,-1)
'String'
>

@mpen 2018-10-12 16:24:49

You might as well use -1 as the 2nd arg to slice and save the regex for a rainy day.

@hygull 2018-10-14 05:43:04

Thanks @mpen. I have added your suggestions.

@Partha Sarathi Nanda 2018-09-27 05:45:40

You can also check with array's length property. When you will try to access length property of an array, it will return a number(0 for empty array) while if you try to access the length property of object it will return undefined.

if(Object.prototype.toString.call(arrayList) === '[object Array]') {
  console.log('Array!');
}

@mpen 2018-09-27 06:20:47

Your paragraph and code example don't align. Also, objects can have a .length property.

@Partha Sarathi Nanda 2018-09-28 08:54:47

You can't check object length. Can u give me a example of object's length property

@mpen 2018-09-28 16:57:52

{length:5} boom. an object with a length property.

@Partha Sarathi Nanda 2018-10-01 05:39:33

wow! this is nice

@Braden Best 2018-07-19 19:12:03

Thankfully, ECMA 5 introduced Array.isArray() back in December 2009. If for some reason, you are using a version of JavaScript older than ECMA 5, please upgrade.

If you insist on it, though, then arrays do have certain properties that differentiate them from any other type. Properties that I haven't seen mentioned in any of the other answers. Let's get into some JavaScript politics.

An array is an object (typeof [] === "object"), but unlike traditional objects, they have a length property (typeof ( {} ).length === "undefined"). null is also an object (typeof null === "object"), but you can't access a property of null because null is not an object. This is a bug in the spec that goes all the way back to the very beginning of JavaScript, when objects had the type tag 0 and null was represented as a literal null pointer 0x00, which caused the interpreter to confuse it with objects.

Unfortunately, this doesn't account for [] vs {length:0}. So we must now turn to the prototype chain.

( [] ).__proto__ === Array.prototype && ( [] ).__proto__ !== Object.prototype.

Thus, without Array.isArray(), this is just about the closest we can get:

function is_array(array){
    return array !== null
        && typeof array === "object"
        && array.__proto__ === Array.prototype;
}

[ [], [1,2,3], {length: 0}, {},
  1, 0, Infinity, NaN, "1", "[1,2,3]",
  null, undefined, [null], [undefined], {a:[]},
  [{}], [{length: 0}], [Infinity], [NaN],
  {__proto__: Array.prototype}
].filter(is_array)
// Expected: [ [], [1,2,3], [null], [undefined], [{}], [{length: 0}], [Infinity], [NaN] ]
// Actual:   [ [], [1,2,3], [null], [undefined], [{}], [{length: 0}], [Infinity], [NaN], {__proto__: Array.prototype} ]

The object maliciously designed to look just like an array actually passes the turing test. However, replacing the prototype chain with the Array prototype chain is enough to make it act just like an array, effectively making it an array. The only thing in the world that can tell such an object is actually not an array, is Array.isArray(). But for the purposes you would usually be checking if an object is an array, said object should play nice with your code. Even the behavior when you change the length of the array artificially is the same: if the length is longer than the number of elements in the array, you WILL have "empty slots" of that special "implicit undefined" type that is somehow distinct from undefined while also being === undefined; the very same type that is the reason we use typeof obj !== "undefined" to avoid throwing a ReferenceError because obj === undefined only doesn't throw an error if obj was explicitly defined as undefined.

a = {__proto__: Array.prototype}; // Array {}
a.push(5)
a // [5]
a.length = 5
a // [5, empty x 4]
b = a.map(n => n*n) // [25, empty x 4]
b.push(undefined)
b.push(undefined)
b // [25, empty x 4, undefined, undefined]
b[1] // undefined
b[1] === b[5] // true
Array.isArray(a) // false
Array.isArray(b) // true

Don't use is_array(), though. It's one thing to reinvent the wheel for learning purposes. It's another thing to do it in production code. Don't even use it as a polyfill. Supporting old JS versions means supporting old browsers means encouraging the use of insecure software means putting the user at risk for malware.

@Alireza 2016-12-27 13:17:10

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 (IE9+, Ch5+, FF4+, Saf5+, Opera10.5+)

Array.isArray(arr);

jQuery:

$.isArray(arr);

Angular:

angular.isArray(arr);

Underscore and Lodash:

_.isArray(arr);

@Ric Flair 2018-05-05 19:07:34

Here's what I use:

function isArray(input) {
  if (input instanceof Array || Object.prototype.toString.call(input) === '[object Array]') {
        return true;
  } else return false;
}

@user113716 2011-01-23 18:54:58

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 string to 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']

@T.J. Crowder 2011-01-23 18:57:56

+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

@neoneye 2011-08-30 09:26:32

This works on Titanium too.

@Ben 2012-08-14 16:11:19

typeof new String('beans') > 'object'

@Pramod 2013-03-15 06:15:03

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

@David Gilbertson 2013-10-11 04:40:51

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/…

@Jakob Sternberg 2013-12-30 16:53:58

Like a baws! function getType(_o){ try{ return Object.prototype.toString.call(_o).substring("[object ")[1].split("]")[0].toLowerCase()}catch(e){}}

@lmsurprenant 2014-02-05 23:53:14

It seems to me like the check for String is simpler than the check for Array...as long as you ignore the caveat about typeof not working with Strings created by new String('hello')

@Greg 2014-02-11 22:36:29

Is there any reason one wouldn't use the shorter syntax if( someVar.toString() === "[object Object]") { ... } ?

@RobG 2014-05-28 06:36:32

@DarkStar1—yes, diseased:[].concat( [] ) returns an empty array, as does undefined and null, so as a test it will rate them all the same.

@cookie monster 2014-07-25 16:34:04

RobG: I don't think the concat() example was meant to be a generalized test. Looks like it's tailored for the specific problem described in the question.

@Freddy 2014-10-08 18:01:50

I prototyped it so i can use it anaywhere: Object.prototype.isArray = function () { if(Object.prototype.toString.call(this) == '[object Array]') { return true; } return false; };

@JLRishe 2014-12-18 18:42:53

@Ben That's not a string; it's a String object.

@jonas 2015-01-27 09:45:10

@Greg Not all objects inherit prototype. try for instance var a = Object.create(null); a.toString(); -> gives uncaught TypeError. stackoverflow.com/questions/4166616/…

@Patrick Finnigan 2015-04-01 23:49:30

note that the summarized question "check if object is array" is better addressed by using Array.isArray() or jquery's isArray, as mentioned in Fela's answer below.

@Lye Fish 2015-04-03 20:03:06

@PatrickFinnigan: I don't think too many browsers supported Array.isArray in Jan. 2011 but it's really just a shorthand for the .toString.call... version. They're exactly equivalent. es5.github.io/#x15.4.3.2 And jQuery definitely isn't needed.

@Patrick Finnigan 2015-04-07 19:59:21

@LyeFish Sure, I am making this comment because it's 2015 and Array.isArray is supported by most browsers now, so to me that is now the correct answer to the question "Check if object is array?" that people should be referred to.

@Andrey 2015-09-24 08:43:15

@mcfedr 2015-11-12 23:53:43

Live in the modern world - Array.isArray(obj)

@John Leidegren 2016-01-11 15:57:37

Why is call significant? Why does Object.prototype.toString([]) return [object Object] and not [object Array]?

@user1106925 2016-02-07 18:22:38

@JohnLeidegren: Because this version of the .toString() method is reporting the [[Class]] property of its this value. The .call() method lets you manually set the value of this in the method being called to the first argument you provide. So with Object.prototype.toString([]), the value of this is the Object.prototype object. But if you use .call(), the value of this is your [] array.

@Brian 2016-04-13 05:02:07

Worth noting that Array.isArray is not supported by IE 8 and below. Also as the function will not return true for array-like objects such as a NodeList (which are returned via querySelectorAll and similar functions).

@Tohid 2016-06-08 17:56:58

in today angular world: angular.isArray(obj);

@Tschallacka 2016-12-05 13:29:23

in this benchmark typeof is fastest jsben.ch/#/tKVuy

@RobG 2017-01-07 09:51:38

@MartinKonicek—jQuery's isArray is identical to the answer where Array.isArray is absent. Why should it be mentioned?

@redfox05 2017-03-30 17:56:15

@T.J.Crowder: Could you elaborate why on your blog you say constructor is not the way to go. Several people on here are noting its the best supported and fastest option? Would really help understand your thoughts.

@T.J. Crowder 2017-03-30 20:23:21

@redfox05: Two reasons: 1. In ES5 code, people tend to forget to set it. 2. It doesn't play well with inheritance. Suppose you have Animal, and from Animal you derive Cat. If you use a constructor check, a cat won't be an animal, which is silly: They are, they're just a specific kind of animal.

@redfox05 2017-03-31 20:44:09

@T.J.Crowder Thanks for the reply! We're creating a util function/class to do the toString method (above) for everything that is not gonna return [object Object] and then use constructor.name for Objects and custom objects. Thoughts? P.s. you also mentioned certain anti-patterns?

@T.J. Crowder 2017-04-01 07:33:28

@redfox05: The function name property is fairly new and only recently supported, so you might have an issue there...

@Douwe de Haan 2017-05-16 11:04:45

Note that in another benchmark performed at jsben.ch, the typeof method is even slightly faster, but has some weird quirks, as mentioned in the beginning of T.J. Crowder's blog

@YouneL 2017-10-29 01:54:57

@DouwedeHaan I think typeof [] will return 'object', I made another benchmark to test instanceof operator and it was the fatest

@STEEL 2018-02-28 17:21:06

You could is isArray method but I would prefer to check with

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

@mpen 2018-02-28 17:36:24

Why would you prefer this?

@STEEL 2018-03-01 10:32:31

@mpen Object.getPrototypeOf(yourvariable) it returns prototype of an Array object. And The code is fastest and safe to rely on.

@mpen 2018-03-01 23:11:16

It's easy to foil: pastebin.com/MP8d5bCE Also, do you have performance tests to back up your "fastest" claim?

@kolyaseg 2017-09-15 09:41:07

In your case you may use concat method of Array which can accept single objects as well as array (and even combined):

function myFunc(stringOrArray)
{
  var arr = [].concat(stringOrArray);

  console.log(arr);

  arr.forEach(function(item, i)
  {
    console.log(i, "=", item);
  })
}

myFunc("one string");

myFunc(["one string", "second", "third"]);

concat seems to be one of the oldest methods of Array (even IE 5.5 knows it well).

@Vikash Kumar 2017-06-08 12:48:15

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.

@ChristoKiwi 2017-06-16 01:38:01

Much cleaner and future safe! This or a typeof comparison.

@Dan Zuzevich 2017-08-20 12:11:40

Is this something that receives a good amount of browser support? I like it.

@abalter 2018-04-27 05:24:29

Unfortunately, this is not actually useful without a try/catch because if "x" is an object such as {} an array, then you get a syntax error.

@lalithkumar 2017-06-05 11:52:55

You can find with push like below:

function isArray(obj){
   return (typeof obj.push=== 'function')?true:false;
}

var array=new Array();
or
var array=['a','b','c'];
console.log(isArray(array));

@yesil 2016-08-24 08:02:43

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

@Alireza 2017-04-09 13:23:50

This is a good trick, but could be overridden... but most of the times should get the result

@sheelpriy 2017-03-01 09:25:55

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

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

or

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

or you can make a utility function:

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

usage:

isArray(arr); //return true

@shinobi 2015-12-06 10:12:39

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

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

@mpen 2015-12-06 21:59:45

You're right, that is the fastest according to the tests I included in the question.

@David Meza 2016-01-26 18:35:26

Are there any downsides to using this method? It seems much more simple and effective than the accepted, top answer.

@unsynchronized 2016-06-26 01:54:42

@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 2016-06-26 06:10:02

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

@shinobi 2016-06-26 06:30:24

@unsynchronized I dont really know of any technical reason. Even I have seen this often, so got used to it.

@unsynchronized 2016-06-26 06:35:41

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

@shinobi 2016-06-26 06:43:32

@unsynchronized: Ah. I see. That could be it. I have actually posted this as a question. stackoverflow.com/questions/38035875/…

@momomo 2017-03-12 21:39:15

doesn't work on isArray(jQuery('div')) .. but is obviously an array... not sure what kind of special array jquery uses but it should be ok

@shinobi 2017-03-13 07:10:55

@momomo jQuery doesnt return an Array. Its returns an array-like object. See this stackoverflow.com/questions/1302428/…

@David A. Gray 2018-04-19 07:51:44

There are definitely downsides to instanceOf; see web.mit.edu/jwalden/www/isArray.html for details.

@mpen 2016-10-24 15:48:01

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.

@Billy Moon 2012-08-08 13:34:01

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
}

@janr 2012-04-02 12:15:39

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>

@Akseli Palén 2012-05-08 22:46:40

@Jacob Squires 2014-04-17 01:25:57

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

@Renan 2014-10-22 14:12:43

@JacobSquires it depends. I just tested here, latest jQuery on Chrome - $.isArray === Array.isArray is returning true.

@awe 2015-12-02 09:55:50

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

@Sergiu 2016-04-24 09:16:40

jQuery is using Array.isArray behind the scenes: github.com/jquery/jquery/blob/master/src/core.js#L211

@Automagisch 2017-02-17 13:46:49

But no one is going to use jQuery JUST FOR this functionality, right? I wouldn't just download jquery because I want to check if something is an array :p

@Kamuran Sönecek 2016-02-25 09:10:23

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

@Kermit_ice_tea 2016-07-27 20:04:19

All the op asked for was a simple efficient check.

@VIJAY P 2016-02-25 05:52:28

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

@Alireza 2017-04-09 13:26:55

there are many easier ways to do this!

@Eugene 2012-04-04 00:46:06

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

@Michał Perłakowski 2016-01-09 21:53:55

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

@le_top 2015-08-01 11:10:28

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

@Gaurav 2015-07-08 12:18:43

 var length = 16;                               // Number
 var lastName = "Johnson";                      // String
 var cars = ["Saab", "Volvo", "BMW"];           // Array
 var x = {firstName:"John", lastName:"Doe"};

 Object.prototype.myCheck= function(){
 if (this.constructor === Array){
          alert('array');
        }else if (this.constructor === Object)
       {
         alert('object');
        }else if (this.constructor === Number)
        {
          alert('number');
        }else if (this.constructor === String)
        {
          alert('string');
        }

 }
 cars.myCheck();
 lastName.myCheck();
 length.myCheck();

@mpen 2015-07-08 16:37:05

Why did you make your method a prototype of Object if you aren't going to call it like cars.myCheck()?

@Gaurav 2015-07-09 17:25:49

yes mark you are correct it should be cars.myCheck().. updated the answer

@mpen 2015-07-09 20:17:50

Still no. If you're making it a prototype method, you should drop the obj argument and use this inside instead. Also, a function that just alerts isn't of much use to anyone.

@George Jempty 2015-04-01 20:35:54

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

@TechTurtle 2017-02-21 17:37:50

constructor is not available in ES5

@George Jempty 2017-02-21 17:49:16

@TechTurtle Are you sure? This code runs in ES6

@user3367643 2015-04-13 12:53:17

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.

@Michał Perłakowski 2016-01-09 22:02:03

var object = {splice: function(){}}; Object.defineProperty(object, "length", {value: 1, enumerable: false}); console.log(is_array(object));

@Sensei_Shoh 2015-04-06 04:37:44

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.

@László Kardinál 2016-02-24 15:19:11

isArray( new String() ); returns true

@Sensei_Shoh 2016-02-24 18:18:39

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"

@rsbkk 2015-04-04 06:58:20

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)

@Bergi 2015-08-07 07:17:17

fooled by {isArray:true}

@Roy Tinker 2016-12-19 20:52:24

JSON.parse(someDataFromElsewhere).items.isArray could return true (depending on the data) and break your code.

@Fela Winkelmolen 2014-01-06 18:11:55

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

@lightswitch05 2014-12-17 18:51:27

Here is a more complete list of browsers that support Array.isArray

@iMatoria 2018-05-21 04:38:07

if (typeof Array.isArray === 'undefined') { could be changed to if(!Array.isArray) {

@Benjamin Gruenbaum 2018-07-06 10:27:15

For what it's worth Object.prototype.string.call(obj) can be spoofed if the object has Symbol.toStringTag on it. That said I am not aware of any environment that ships Symbol.toStringTag but not Array.isArray so this seems safe.

@NobleUplift 2018-08-20 21:45:24

Why does instanceof Array fail if the array is from a different frame?

@jschoi 2018-09-22 07:45:58

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

@Brad Parks 2014-02-02 00:29:54

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

Related Questions

Sponsored Content

60 Answered Questions

[SOLVED] How do I correctly clone a JavaScript object?

60 Answered Questions

[SOLVED] How can I merge properties of two JavaScript objects dynamically?

37 Answered Questions

[SOLVED] How do I remove a property from a JavaScript object?

33 Answered Questions

[SOLVED] For-each over an array in JavaScript?

45 Answered Questions

76 Answered Questions

[SOLVED] How do I remove a particular element from an array in JavaScript?

  • 2011-04-23 22:17:18
  • Walker
  • 5598585 View
  • 6939 Score
  • 76 Answer
  • Tags:   javascript arrays

30 Answered Questions

[SOLVED] How to append something to an array?

20 Answered Questions

[SOLVED] Checking if a key exists in a JavaScript object?

47 Answered Questions

53 Answered Questions

[SOLVED] How do I check if an element is hidden in jQuery?

Sponsored Content