Suggest an editImprove this articleRefine the answer for “typeof for an array”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`typeof []` returns the string `"object"`, because in JavaScript an array is a special kind of object, not a separate primitive type.** Internally an array is an object whose keys are numeric indexes (`"0"`, `"1"`, `"2"`) and whose `length` property tracks the number of elements. The `typeof` operator simply has no dedicated name for arrays, so the check you want is `Array.isArray(value)`, which is reliable and also works across realms (iframe, worker). ```javascript console.log(typeof []); // "object" console.log(Array.isArray([])); // true ``` **Key point:** `typeof []` is always `"object"`, and the real array check is `Array.isArray()`.Shown above the full answer for quick recall.Answer (EN)Image**`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 `length` holding the element count. - The list of `typeof` results is fixed: `"undefined"`, `"boolean"`, `"number"`, `"bigint"`, `"string"`, `"symbol"`, `"function"`, `"object"`. - The correct array check is `Array.isArray(value)`. - `value instanceof Array` also 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 ```javascript console.log(typeof []); // "object" console.log(typeof {}); // "object" console.log(typeof null); // "object" console.log(Array.isArray([])); // true console.log([] instanceof Array); // true ``` Three 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"`); - **`length`** updates automatically and is always one greater than the largest index; - its prototype is `Array.prototype`, which supplies `map`, `filter`, `push` and the rest. ```javascript const arr = ['a', 'b']; console.log(Object.keys(arr)); // ["0", "1"] console.log(arr.length); // 2 console.log(Object.getPrototypeOf(arr) === Array.prototype); // true ``` The 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. ```javascript 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. ```javascript Array.isArray([]); // true Array.isArray([1, 2, 3]); // true Array.isArray('abc'); // false Array.isArray({ length: 0 }); // false ``` The alternative is `instanceof`, which walks the prototype chain: ```javascript [] instanceof Array; // true ``` It answers correctly inside one window, but an array created in an `iframe` or another context has its own `Array.prototype`, and the check fails: ```javascript 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)); // true ``` A third option is calling the standard `toString`, which returns the object's internal tag: ```javascript 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 `typeof` to 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 for `null`, `{}`, `Date`, `Map` and every other object. - **Forgetting `null`.** `typeof null` is `"object"` too, a long-standing language bug kept for compatibility. Check the value separately before reading properties off it. - **Relying on `instanceof` in code that deals with an `iframe`, a `worker` or a server context.** There the value arrives from another realm and `instanceof` returns `false` for a genuine array. - **Confusing arrays with array-likes.** `arguments`, `NodeList` and any object with a `length` field behave similarly, but `Array.isArray()` returns `false` for them. To get a real array, use `Array.from(value)` or `[...value]`.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.