typeof for an array
typeof [] returns "object", because in JavaScript an array is not a separate data type but a specialised object. The typeof operator returns the type name as a string, and "array" is simply not one of the values it can produce.
Theory
TL;DR
typeof []is"object", not"array".- An array is an object whose keys are numeric indexes stored as strings, with
lengthholding the element count. - The list of
typeofresults is fixed:"undefined","boolean","number","bigint","string","symbol","function","object". - The correct array check is
Array.isArray(value). value instanceof Arrayalso works, but breaks when the array comes from another realm (iframe, worker, separate context).Object.prototype.toString.call([])returns"[object Array]", an older but still working trick.
Quick example
console.log(typeof []); // "object"
console.log(typeof {}); // "object"
console.log(typeof null); // "object"
console.log(Array.isArray([])); // true
console.log([] instanceof Array); // trueThree values with completely different meanings give the same "object" answer, so typeof on its own cannot tell an array from a plain object or from null.
Why an array is an object
In the language specification an array is an exotic object with special behaviour for its length property. Internally it is arranged like this:
- keys are numeric indexes stored as strings (
"0","1","2"); lengthupdates automatically and is always one greater than the largest index;- its prototype is
Array.prototype, which suppliesmap,filter,pushand the rest.
const arr = ['a', 'b'];
console.log(Object.keys(arr)); // ["0", "1"]
console.log(arr.length); // 2
console.log(Object.getPrototypeOf(arr) === Array.prototype); // trueThe same thing is visible from the other direction: you can give a plain object indexes and a length by hand and it will look like an array, yet it will not be one.
const arrayLike = { 0: 'a', 1: 'b', length: 2 };
console.log(Array.isArray(arrayLike)); // false
console.log(Array.from(arrayLike)); // ["a", "b"]How to check for an array correctly
The main tool is Array.isArray(). It inspects an internal slot of the object rather than the prototype, so it does not depend on the execution context.
Array.isArray([]); // true
Array.isArray([1, 2, 3]); // true
Array.isArray('abc'); // false
Array.isArray({ length: 0 }); // falseThe alternative is instanceof, which walks the prototype chain:
[] instanceof Array; // trueIt answers correctly inside one window, but an array created in an iframe or another context has its own Array.prototype, and the check fails:
const frame = document.createElement('iframe');
document.body.appendChild(frame);
const foreignArray = new frame.contentWindow.Array(1, 2, 3);
console.log(foreignArray instanceof Array); // false
console.log(Array.isArray(foreignArray)); // trueA third option is calling the standard toString, which returns the object's internal tag:
Object.prototype.toString.call([]); // "[object Array]"
Object.prototype.toString.call({}); // "[object Object]"
Object.prototype.toString.call(null); // "[object Null]"Comparing the checks
| Check | Returns | Comment |
|---|---|---|
typeof [] | "object" | An array is an object; there is no separate type name |
Array.isArray([]) | true | The correct way, works across realms |
[] instanceof Array | true | Also correct, but depends on the execution context |
Object.prototype.toString.call([]) | "[object Array]" | Works everywhere, but verbose |
[].constructor === Array | true | Easy to break by overwriting constructor |
Common mistakes
- Expecting
typeofto return"array". That result does not exist: the operator's set of answers is fixed by the specification, and arrays fall under"object". - Testing for an array with
typeof value === 'object'. That condition is also true fornull,{},Date,Mapand every other object. - Forgetting
null.typeof nullis"object"too, a long-standing language bug kept for compatibility. Check the value separately before reading properties off it. - Relying on
instanceofin code that deals with aniframe, aworkeror a server context. There the value arrives from another realm andinstanceofreturnsfalsefor a genuine array. - Confusing arrays with array-likes.
arguments,NodeListand any object with alengthfield behave similarly, butArray.isArray()returnsfalsefor them. To get a real array, useArray.from(value)or[...value].
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.