back to index

Checking 'Is This an Array?' in JS

Array.isArray, instanceof, and Object.prototype.toString.call, and where each one breaks.

published Sep 09, 2018 tags #javascript #types

~/posts/is-array $ cat post.md

/ LANG EN / 中文
/ THEME / /

Overview

There are several ways to ask “is this an array?”. When I’m writing TypeScript I default to value instanceof Array — articles say it’s reliable because it walks the prototype chain looking for Array. That holds up under Node, but the browser exposes a few cases where it returns the wrong answer.

Here’s a run-through of the usual options and where each one cracks.

Trust the C++

The most robust check is V8’s Value->IsArray():

  • Node and the browser both surface it as Array.isArray(value) — it inspects the actual in-engine type instead of walking JS-level prototypes.
  • Fastest, most stable, most portable.
  • The only limit is browsers older than ES5, which don’t have it.

Educated guesses

The other methods work most of the time but have rough edges.

value instanceof Array;

instanceof and value.constructor === Array are mechanically similar — both compare against a single Array reference. Two gotchas:

  • A side-effect-laden library might rebind Array to a different class.
  • In a browser, a service worker or an iframe lives in its own realm with its own Array. A value crossing the boundary won’t be instanceof the outer realm’s Array.
Object.prototype.toString.call(value) === "[object Array]";

Works in most cases. The exception is “array-likes” — iterable non-arrays such as arguments, NodeList, or anything with a custom Symbol.iterator. For those, this returns "[object Object]".

In practice

The short answer:

  • If Array.isArray is available, use it. It correctly returns true for arrays from other realms (iframes, workers); instanceof does not.
  • For pre-ES5 environments, fall back to Object.prototype.toString.call, with an explicit Symbol.iterator check if array-likes are something you care about.
  • instanceof Array is fine only inside a self-contained scope where you control Array and nothing crosses realms.
back to index