1. typeof
まず思いつくのは typeof を使用してデータ型を検出することです。しかし、Function、String、Number、Undefined などの基本型の場合、typeof で検出できます。例えば次のコードのようになります:
function test(){}
console.log(typeof 1);
console.log(typeof test);
console.log(typeof "yunxi");
console.log(typeof undefined);
しかし、配列や正規表現の場合、typeof で検出すると対応できません。配列や正規表現を検出すると、返される型はオブジェクト(object)になります。次のコードのようになります:
console.log(typeof []);
console.log(typeof /\d+/g);
2. Instanceof
これにより、instanceof を使用してオブジェクトが配列のインスタンスであるかどうかを検出することを容易に思いつくでしょう。この検出はブール型(boolean)を返します。配列の場合は true を返し、それ以外の場合は false を返します。上記の配列かどうかの検出コードを再度見てみましょう:
console.log([] instanceof Array);
console.log(/\d+/g instanceof Array);
上記のように、instanceof を使用して配列かどうかを判定できることがわかります。
3. constructor プロパティ
JavaScript では、すべてのオブジェクトに constructor プロパティがあります。これはそのオブジェクトを初期化したコンストラクタ関数を参照します。未知のオブジェクトの型を判定するために、次のようなメソッドを書くことができます。コードは以下の通りです:
function isArray(obj) {
return typeof obj == 'object' && obj.constructor == Array
}
console.log(isArray([]));
var a = {"a":1};
console.log(isArray(a));
var b = [1,2,3];
console.log(isArray(b));
console.log(isArray(/\d+/g));
上記のように、isArray メソッドを呼び出すことでも配列かどうかを判定できることがわかります。
さて、第2点と第3点では、それぞれ instanceof メソッドと constructor プロパティを使用することで配列かどうかを判定できそうに見えます。しかし、例外もあります。例えば、フレームをまたぐ iframe でページ内の配列を使用する場合、失敗します。異なるフレーム(iframe)では、作成された配列は互いに prototype プロパティを共有しないためです。次のコードでテストすると検証できます。
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
xArray = window.frames[window.frames.length-1].Array;
var arr = new xArray("1","2","3","4","5");
console.log(arr);
console.log(arr instanceof Array);
console.log(arr.constructor === Array);
上記の方法では、オブジェクトが配列かどうかを判定することはできません。しかし、ECMA262 を参照すると、Object.prototype.toString.call() メソッドを使用してオブジェクトが配列かどうかを判定できることがわかります。次のコードのようになります:
function isArray(obj) {
return Object.prototype.toString.call(obj) == '[object Array]';
}
console.log(isArray([]));
console.log(isArray([1,2,3]));
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
xArray = window.frames[window.frames.length-1].Array;
var arr = new xArray("1","2","3","4","5");
console.log(arr);
console.log(isArray(arr));