JavaScript で配列を判定する方法として、ECMA Script 5では Array.isArray() が用意されています。
alert(Array.isArray([1, 2, 3])); //配列なので true
alert(Array.isArray([])); //空の配列でも true
alert(Array.isArray({})); //オブジェクトは false
しかし、IE8は ECMA Script 5 にほぼ対応していないので、このメソッドは使えません(cf. ECMAScript 5 compatibility table)。
では、IE8含めて対応するにはどうするか。
まず、typeof でいけないか? と考えますが、"object" が返ってきてしまうので、使い物になりません。
そこで、instanceof を使ってみます。
var foo = [];
var bar = {};
alert(foo instanceof Array); // true
alert(bar instanceof Array); // false
このように、hoge instanceof Array と書くと hoge が Array のインスタンスかどうかを真偽値で返してくれるわけです。
似たような名前の typeof が typeof hoge で型を表す文字列を返してくれるのに対して、こちらは真偽判定なので、使い方でちょっと混乱しそうですね。ちなみに instanceof はプロトタイプチェーンを遡って判定するため、多重継承っぽいことをしている場合、真となるオブジェクトはひとつではありません。たとえば Array は Object でもあるので、上の例で続いて foo instanceof Object とすれば true が返ってきます。
それはともかく、この方法は厳密には正解ではありません。たとえばフレームを使っているページ(window.open() などで新しいウィンドウを生成した場合も同様)では、ページ(ウィンドウ)ごとに Array という別オブジェクトが存在することになるので、たとえば親フレームにある hoge という変数が配列かどうかを判定したいとき parent.hoge instanceof Array としても false になるわけです。
hoge.constructor === Array で判定するというやり方もありますが、やはり上記と同じ理由により、正確ではありません。
このような別フレームの変数を参照して配列かどうか判定することはそうあることではないと思うので、場合によってはそれを理解した上で使っても構わないと思います。しかし、もしこれも踏まえて正確に判定するようにしたいのであれば、以下の方法が良いようです。
isArray([]); // true
isArray({}); // false
isArray(parent.hoge); // 親フレームにhogeという配列がある前提で、 true
function isArray(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
}
いったん文字列に変換してしまうわけです。うーん、なんか気持ち悪い……。しかしこれは仕様上保証されている動作なので、ブラウザの実装に依存せず判定をすることができるようです。
なお、jQuery には jQuery.isArray() というメソッドクロスブラウザ対応のメソッドが用意されているので、 jQuery 使用時にはこれを使うのが無難かもしれません。jQuery のソースを確認すると、やはりこちらも文字列に変換して判定する実装になっているようですね。
参考:
http://stackoverflow.com/questions/218798/in-javascript-how-can-we-identify-whether-an-object-is-a-hash-or-an-array
http://stackoverflow.com/questions/4775722/check-if-object-is-array
http://stackoverflow.com/questions/767486/how-do-you-check-if-a-variable-is-an-array-in-javascript
http://stackoverflow.com/questions/1058427/how-to-detect-if-a-variable-is-an-array