Checking whether a value is an array
To check whether a value is an array, use Array.isArray(value). A dedicated function is needed because in JavaScript an array is a kind of object, and typeof [] returns 'object', which distinguishes nothing.
Theory
TL;DR
Array.isArray(value)is the modern and reliable way, standardised in ES5.- It works even when the array was created in another context (an iframe or a separate window).
value instanceof Arrayreads clearly but returnsfalsefor an array from a foreign context.Object.prototype.toString.call(value) === '[object Array]'is the old fallback.typeofdoes not fit this task: it returns'object'for an array.- An array-like object (
{ length: 2 }) is not an array, and no check will say otherwise.
Quick example
console.log(Array.isArray([1, 2, 3])); // true
console.log(Array.isArray('hello')); // false
console.log(Array.isArray({ length: 0 })); // false
console.log(Array.isArray(new Array())); // true
console.log(Array.isArray(null)); // falseWay 1: Array.isArray()
Array.isArray(value);This is the standard ES5 method created specifically for this check. It returns true when the value is an array and false in every other case.
Array.isArray([1, 2, 3]); // true
Array.isArray([]); // true
Array.isArray('text'); // false
Array.isArray({ 0: 'a', 1: 'b', length: 2 }); // false
Array.isArray(null); // falseThe method also works correctly across execution contexts (an iframe, a separate window and so on), because it inspects the value's internal slot rather than its prototype. That is what makes it the only fully reliable way.
Way 2: instanceof Array
value instanceof Array;An example:
console.log([1, 2, 3] instanceof Array); // true
console.log({} instanceof Array); // falseThe drawback: if the array was created in another window or in an iframe, the check returns false, because that array has a different Array constructor:
// every context has its own global Array
iframe.contentWindow.Array !== window.Array;instanceof walks the prototype chain, and prototypes from different contexts are different objects. On top of that, the check can be fooled by replacing an object's prototype.
Way 3: Object.prototype.toString
Object.prototype.toString.call(value) === '[object Array]';An example:
console.log(Object.prototype.toString.call([1, 2, 3])); // "[object Array]"
console.log(Object.prototype.toString.call({})); // "[object Object]"It works correctly, including across contexts, but it looks bulky, so these days it is almost always replaced with Array.isArray(). Historically it was the main approach before ES5, and it still shows up in polyfills.
Comparing the approaches
| Method | Returns | Pros | Cons |
|---|---|---|---|
Array.isArray() | true / false | Modern, reliable, readable | None |
instanceof Array | true / false | Clear syntax | Does not work across contexts |
Object.prototype.toString.call() | "[object Array]" | Always works | Verbose to write |
Common mistakes
- Checking with
typeof.typeof []gives'object', exactly like{}andnull, so nothing is distinguished. - Relying on a
lengthproperty. A string andargumentshavelengthtoo, yet neither is an array. - Using
instanceofon data from an iframe or another window. There the globalArrayis a different one, and the check silently returnsfalse. - Confusing "array-like" with "array".
argumentsandNodeListare array-like collections: you can iterate them, but they have no array methods.Array.from()converts them. - Forgetting that
nullis'object'too. An array check cannot be replaced bytypeof value === 'object'.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.