【実務・中級編】 Array.isArray と instanceof Array の違い – JavaScript実践ガイド

やあ。フロントエンドの沼にどっぷり浸かっている君なら、一度は「配列の判定」で頭を抱えたことがあるはずだ。

「とりあえず `instanceof Array` でいいや」なんてコードを書いていないか? もしそうなら、今日はそれを卒業する日だ。大規模なSPAや、外部ライブラリ、あるいはiframeを駆使した複雑な環境で、その書き方がいかに「時限爆弾」になり得るかを解説しよう。

—

なぜ `instanceof Array` は「裏切り者」なのか

まず、結論から言おう。`instanceof` は、「同じ実行コンテキスト(Realm)」の中にいることが絶対条件だ。

JavaScriptのオブジェクトは、生成された環境のプロトタイプチェーンを継承する。しかし、iframeや別のウィンドウ、あるいはNode.jsのVMコンテキストといった「独立したグローバル環境」をまたぐと、話が変わってくる。

現場で遭遇する「見えない壁」

例えば、親ウィンドウで生成した配列を `iframe` 内の関数に渡したとする。iframe側のグローバルスコープには「iframe専用の `Array` コンストラクタ」が存在する。親の配列が持つ `__proto__` は、親の `Array.prototype` を指している。

つまり、iframe側で `myArray instanceof Array` と判定すると、「お前は俺の知っているArrayの親戚じゃない」と判定されて `false` が返るわけだ。これ、デバッグ時に本当に泣きたくなるやつだぞ。

—

救世主 `Array.isArray` の設計思想

そこで登場するのが `Array.isArray` だ。これは ES5 で導入された標準メソッドだが、その裏側は非常に堅牢に設計されている。

ブラウザの内部実装では、このメソッドは「プロトタイプチェーン」を一切信用しない。その代わりに、オブジェクト内部の `[[Class]]` 内部スロットを直接覗きに行くんだ。

  • `instanceof`: 「プロトタイプチェーンを辿って、コンストラクタが一致するか?」という関係性を見る。
  • `Array.isArray`: 「お前、中身は紛れもなく配列という構造をしているか?」という本質を見る。

この本質を見抜く力こそが、マルチコンテキスト環境でバグを生まないための必須スキルというわけだ。

—

実践:現場で使うべき「鉄板コード」

実務において、自分で判定ロジックを書く必要はほぼない。ただ、もし何らかのライブラリ開発や、極めて厳密な型チェックが必要な場面であれば、以下のように書くのがベストプラクティスだ。

/

  • 現場で迷ったらこれを使え。
  • Array.isArrayは、環境を跨いでも正しく「配列である」ことを教えてくれる。

/
function isTrulyArray(value) {
// 1. まずは標準のArray.isArrayを信じるのが鉄則
if (Array.isArray(value)) {
return true;
}

// 2. もしレガシー環境(IE8以下)を考慮する極端な現場なら、
// Object.prototype.toString を使うのが伝統的なハックだ
return Object.prototype.toString.call(value) === ‘[object Array]’;
}

// 動作確認:iframeを通しても破綻しない
const iframe = document.createElement(‘iframe’);
document.body.appendChild(iframe);
const iframeArray = new iframe.contentWindow.Array(1, 2, 3);

console.log(iframeArray instanceof Array); // -> false (裏切り者!)
console.log(Array.isArray(iframeArray)); // -> true (真の友!)

—

シニアからのアドバイス:深追いしすぎない勇気

もちろん、`instanceof` が全く役に立たないわけじゃない。自分たちが設計したクラス(`class User { … }` など)の判定には `instanceof` が適切だ。なぜなら、それらはその環境内で定義された唯一無二の存在だからだ。

しかし、`Array`, `Object`, `Date`, `RegExp` といった「ブラウザ標準の組み込みオブジェクト」については、常に環境の境界線を疑うべきだ。

  • 「Arrayか?」と聞かれたら、迷わず `Array.isArray` を使う。
  • 「自作クラスのインスタンスか?」と聞かれたら、`instanceof` を使う。

この使い分けができるだけで、君の書くコードの「堅牢性」は一段階上のレベルへ到達する。JavaScriptは柔軟で強力な言語だが、その分、仕様の裏側を少しだけ覗き見る好奇心を持つやつが、最終的に一番強いコードを書くんだ。

現場からは以上だ。また何かあればいつでも聞きに来い。

コメント

タイトルとURLをコピーしました