Array.isArray([]) vs. Object.prototype.toString.call([])

How to Check for an Array in JavaScript

JavaScript arrays are a type of object, so typeof [] returns "object" — not very helpful to see if you have an array. Here are 5 methods to check whether a JavaScript object is an array.

Image for post
Image for post
Photo by JJ Ying on Unsplash

A common problem in JavaScript data validation is checking to see whether a given variable contains an array.

For primitive types, the typeof keyword usually works pretty well, but the typeof an array is "object": typeof [] === object // true.

While that makes sense (arrays are a built-in type of JavaScript object, after-all), it is not useful for differentiating arrays from other objects.

Plus, getting "object" from typeof could indicate a null value.

Thankfully, there are many ways to check for a JavaScript array:

  • Method 1) Array.isArray([])
  • Method 2) Object.prototype.toString.call([])
  • Method 3) [] instanceof Array
  • Method 4) [].constructor
  • Method 5) && with [].constructor

In this article, I’ll explain the pros and cons of each approach.

Method 1: Array.isArray([])

ECMAScript 5 (ES5) introduced the Array.isArray() method to check for an array, since typeof will not be able to differentiate arrays from other objects, such as the built-in objects Date and RegExp.

Using Array.isArray() is also useful for making sure that our object is not null, as null has the typeof "object" due to a long-standing bug.

Here is an example of checking for an array using Array.isArray([]):

Image for post
Image for post
View raw code as a GitHub Gist

Method 2: Object.prototype.toString.call([])

The verbose JavaScript statement Object.prototype.toString.call() can differentiate between arrays and other types of objects, because it returns a string that specifies the object type in more detail than typeof.

Because this method will work for any object, I call it the best way to type check in JavaScript. Here is an example:

Image for post
Image for post
View raw code as a GitHub Gist

While verbose, this method will work for any primitive type and for any object. It always returns the name of the constructor for the variable.

Put another way, Object.prototype.toString.call() is sort-of like instanceof in reverse, though it works fine inside of iframes.

The behavior of the above isArray() function should be identical to the built-in Array.isArray() function.

One thing to note here is that typeof {} returns "object" (lowercase), but Object.prototype.toString.call({}).slice(8,-1) returns "Object" (uppercase) for an object {} and "Array" (uppercase) for an array [].

As with all of these methods, this method will not work if the variable has not yet been declared. I’ll address checking for undeclared variables later.

Method 3: [] instanceof Array

Using the keyword instanceof can be used to check for arrays or any type of JavaScript object.

“The instanceof operator tests to see if the prototype property of a constructor appears anywhere in the prototype chain of an object.” — MDN Docs

The syntax is straightforward, as shown in this code example:

Image for post
Image for post
View raw code as a GitHub Gist

Watch out though, iframes can break this behavior, as explained in the Mozilla Developer Network documentation for Array.isArray:

instanceof vs isArray

When checking for [an] Array instance, Array.isArray is preferred over instanceof because it works through iframes. — MDN Docs

That means that we may not want to use instanceof to check for an array at all, just in case our JavaScript code ends up running inside an iframe.

Method 4: [].constructor

For completeness, I want to mention a method similar to instanceof — calling the .constructor property of a JavaScript object.

The .constructor property will return the constructor function, which for an array will be the function Array() (i.e. the JavaScript class Array).

Accessing the .name property of that function will give the string "Array", which can be used to form a simple check for the presence of an array.

Since the .constructor property returns function Array() (i.e. the JavaScript class Array), you can also compare it directly to the global Array object (which is what is referenced by the returned function Array()).

In other words, you don’t actually have to use the .name property; [].constructor===Array is equivalent to [].constructor.name==="Array".

Here is a code example:

Image for post
Image for post
View raw code as a GitHub Gist

Similar to Object.prototype.toString.call(), accessing the .constructor property will work for any type of JavaScript value, including primitives — though you can’t access .constructor for undefined or null values.

(Note that the instanceof keyword will work for objects, but not for primitives. And, of course, instanceof is bugged in iframes.)

As we see above, using .constructor without a null check results in a TypeError for both null and undefined — a downside compared to Array.isArray(), which would just return false for those two values.

And, as with any of the methods covered so far, undeclared variables will throw a ReferenceError if you try to access them.

A word of warning: .constructor is mutable

Before moving on, it is worthwhile to note that .constructor is not robust, because it is an object property that can be overwritten at a later time.

“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.” – ghaschel in his Stack Overflow answer

So just remember that an object’s .constructor property is “mutable” — it could have been changed somewhere in the code from its original value.

Method 5: && and [].constructor (null check! 😄)

Here is a neat one-liner that will check for a non-null value at the same time that you check for an array: [] && [].constructor === Array.

Both null and undefined are falsy values, meaning they evaluate to false in conditional statements, but all objects are truthy, including empty arrays. Checking [] && [].constructor === Array will return false for null or undefined values, while .constructor alone would throw an error.

Including the logical AND (&&) operator has the advantage of avoiding the TypeError that occurs because null and undefined have no properties. This works because && is a “short-circuit operator.” By using the logical AND (&&), we check that the value is truthy before attempting to access the .constructor property. Here is a code example:

Image for post
Image for post
View raw code as a GitHub Gist

To improve code-readability, you might consider making the null check explicit using loose equality: [] != null && [].constructor. Using != (the loose equality operator) means null and undefined equal each other.

An even more explicit check would use strict equality: [] !== null && [] !== undefined && [].constructor === Array. Many JavaScript programmers prefer to never use loose equality, since the rules for == are confusing.

Using && with .constructor effectively works the same way for null and undefined as Array.isArray() does: it returns false, as you would hope.

However, undeclared variables will still throw a ReferenceError when trying to access the .constructor property. You can use typeof to check that the value is not "undefined" before the array check to solve that problem.

What if the array variable is actually undeclared?

You may be unsure if the variable that may be an array has actually been declared yet. Let me talk briefly about checking for undeclared arrays.

As a reminder, accessing a variable that has not been declared will throw a ReferenceError, while a variable that has been declared but not assigned a specific value will have the value of undefined.

Thankfully, the typeof keyword will return "undefined" for a variable that has not yet been declared, same as it will for the value undefined, but without throwing a ReferenceError because the variable hadn’t been .

That means we can wrap Array.isArray() inside of a typeof call in order to make it robust against undeclared variables. Here is an example:

Image for post
Image for post
View raw code as a GitHub Gist

Alternatively, we could use a try...catch block, catching the potential ReferenceError, but typeof works just as well for undeclared variables.

How to check for an empty array in JavaScript?

If instead we want to check to see if an array may be empty, we can check its .length property — an empty array has .length of 0.

Again, we need to be sure that we are working with a declared variable that has already been assigned a value that is definitely an array.

But, assuming we got true from Array.isArray([]), then [].length > 0 will confirm that our array is not empty. Here’s a code snippet:

Image for post
Image for post
View raw code as a GitHub Gist

Again, we are taking advantage of && working as the short-circuit operator. Because it “short-circuits” on false statements, we never reach the .length call in the example above. That’s exactly what we want, because .length won’t work on most primitives like numbers or other types of objects.

Performance Testing: What’s the fastest way to check for an array in JavaScript?

Developer Mark Penner (mpen) used jsPerf to compare various methods of checking for an array in JavaScript.

His results show that one popular method is 20% slower than the others — though the difference is negligible, since the results are so fast.

Here is what I got when I ran his jsPerf test suite a few months back:

Image for post
Image for post
These jsPerf test results show that Object.prototype.toString.call([]) is about 20% slower than other methods, such as Array.isArray().

(Author’s note: jsPerf is currently down pending some configuration to relaunch it. I hope the authors get it working again soon. 🙏)

The summary is that Array.isArray() is as fast as .constructor or instanceof, but Object.prototype.toString.call([]) is slower.

The results support using Array.isArray() by default, though your personal preference could be using .constructor with a null check.

But if you’re a fan of Object.prototype.toString.call([]) — don’t sweat it! The differences show that this slightly-slower method is still very fast: over 700,000,000 operations per second on my home PC.

So unless you are making trillions of array checks, you won’t see a significant difference in your code’s speed by swapping any one method for another.

Conclusion: How to Check for a JavaScript Array

Because the keyword typeof returns "object" for null and all objects — including arrays — checking for arrays requires another tool.

Array-specific methods

The ES5 helper method Array.isArray() will quickly and simply tell you whether any JavaScript variable is an array: Array.isArray([]) // true, and it works for null and undefined(but not undeclared variables).

That Array.isArray() method is widely-supported across all browsers, since Internet Explorer 9, as it was part of the ECMAScript 5 specification.

You may see instanceof used: [] instanceof Array // true, but instanceof is not recommend as it does not work inside of iframes.

Methods that work for any object

There are several methods that are useful for checking for arrays because they can be used to determine the type of any JavaScript object.

The more generic method Object.prototype.toString.call([]) // "[object Array]" will tell you what type of object any value is, including primitives.

In order to just capture the type, that string can be processed with .slice(): Object.prototype.toString.call([]).slice(8,-1) // Array

Similarly, the .constructor property will return the constructing function of a JavaScript value. For arrays, this is the built-in global function Array().

That function can be compared to the global object (i.e.Array), or the constructor function’s .name property can be accessed as a string: [].constructor.name // "Array".

However, .constructor has the drawback that you could assign a new value to it, thus negating your array check: [].constructor = 3 // valid

Checking for undeclared arrays

The keyword typeof will not differentiate arrays from other objects, though typeof remains useful for screening out undeclared variables.

When the typeof keyword returns "object" then we know the variable has been declared and assigned either an object or a null value.

Meanwhile, typeof will return "undefined" for undeclared variables instead of throwing a ReferenceError, making it useful to check typeof first if you think you might be working with an undeclared variable.

Once we know the variable is declared using typeof (whether === "object" or !== "undefined"), we can use Array.isArray() with certainty.

Checking for empty arrays

Finally, when we are sure we have an array (i.e. when Array.isArray() returns true), we can check if the array is empty using .length.

A .length of 0 indicates an empty JavaScript array [] , while an array with .length > 0 indicates a non-empty array.

Note that the empty array [] is truthy, meaning it returns true when evaluated as a Boolean. ([] is truthy because all objects are truthy.)

The best method to check for an array

I covered 5 different methods of checking for a JavaScript array. I generally use Array.isArray() when I’m coding for several reasons:

  • Array.isArray() is fast and broadly-supported.
  • Array.isArray() is explicit, making your code more readable.
  • Array.isArray() returns false for null and undefined.

Sometimes, I’ll wrap my array check inside a if(typeof !== "undefined") statement in the rare case that I am worried about undeclared variables.

But otherwise, I’m just gonna use Array.isArray() — it just works.

Now get out there and check for arrays confidently!

Happy coding! 💻🎶👓💯🤩

Further reading

  • Brilliant author Samantha Ming discusses why not to use instanceof:

Join my email list to get free access to all of my Medium articles.

JavaScript In Plain English

New JavaScript + Web Development articles every day.

Dr. Derek Austin 🥳

Written by

🤓 The physical therapist who writes JavaScript 💪 Web Developer 😎 Mentor 🧠 DPT 😄 SEO Expert 😁 React 😆 Jamstack 💬 Ask me anything 👉 DoctorDerek.com 👈

JavaScript In Plain English

New JavaScript + Web Development articles every day.

Dr. Derek Austin 🥳

Written by

🤓 The physical therapist who writes JavaScript 💪 Web Developer 😎 Mentor 🧠 DPT 😄 SEO Expert 😁 React 😆 Jamstack 💬 Ask me anything 👉 DoctorDerek.com 👈

JavaScript In Plain English

New JavaScript + Web Development articles every day.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app