Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
151
Help us understand the problem. What is going on with this article?
@myzkyy

JavaScript で配列を判定する正しいやり方

More than 5 years have passed since last update.

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 のインスタンスかどうかを真偽値で返してくれるわけです。

似たような名前の typeoftypeof 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

151
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
myzkyy
最近は TypeScript, React[ Native], Vue.js, Firebase あたりをメインに触っています(Qiita で記事を書いているとは言っていない)。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
151
Help us understand the problem. What is going on with this article?