【Javascript】配列とオブジェクトを見分ける


```js:配列か判定する関数

var is_array = function (value) {
 return value && typeof value === 'object' && value.constructor === Array;
};


var is_array2 = function (value) {
    return value && 
           typeof value === 'object' && 
           typeof value.length === 'number' && 
           typeof value.splice === 'function' && !(value.propertyIsEnumerable('length'));
};

if(!Array.isArray) {  
  Array.isArray = function (vArg) {  
    return Object.prototype.toString.call(vArg) === "[object Array]";  
  };  
}

```


```html:フレームで生成された配列がis_array関数でfalse、is_array2関数とArray.isArray関数でtrueになるサンプル

<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<title></title>
</head>
<body>
<h2>Javascript The Good Parts</h2>

6章 配列<br/>
配列かどうか判定 P70<br/>

<br/>
<iframe name="hoge" src=""></iframe>
<br/>
<iframe name="hoge2" src=""></iframe>
<br/>

<script type="text/javascript">

var is_array = function (value) {
 return value && typeof value === 'object' && value.constructor === Array;
};


var is_array2 = function (value) {
    return value && 
           typeof value === 'object' && 
           typeof value.length === 'number' && 
           typeof value.splice === 'function' && !(value.propertyIsEnumerable('length'));
};

if(!Array.isArray) {  
  Array.isArray = function (vArg) {  
    return Object.prototype.toString.call(vArg) === "[object Array]";  
  };  
}

var frm_doc=parent.frames[0].Array(1,2,"demon-uploader",2014,true);

document.writeln("<br/>");
document.writeln("frm_doc[0]="+frm_doc[0]+"<br/>");
document.writeln("frm_doc[1]="+frm_doc[1]+"<br/>");
document.writeln("frm_doc[2]="+frm_doc[2]+"<br/>");
document.writeln("frm_doc[3]="+frm_doc[3]+"<br/>");
document.writeln("frm_doc[4]="+frm_doc[4]+"<br/>");
document.writeln("<br/>");
document.writeln("is_array(frm_doc)="+is_array(frm_doc)+"<br/>");
document.writeln("is_array2(frm_doc)="+is_array2(frm_doc)+"<br/>");
document.writeln("Array.isArray(frm_doc)="+Array.isArray(frm_doc)+"<br/>");

var frm_doc2 = new hoge2.Array("kyoshiro","demon-uploader",false, 2014);

document.writeln("<br/>");
document.writeln("frm_doc2[0]="+frm_doc2[0]+"<br/>");
document.writeln("frm_doc2[1]="+frm_doc2[1]+"<br/>");
document.writeln("frm_doc2[2]="+frm_doc2[2]+"<br/>");
document.writeln("frm_doc2[3]="+frm_doc2[3]+"<br/>");
document.writeln("<br/>");
document.writeln("is_array(frm_doc2)="+is_array(frm_doc2)+"<br/>");
document.writeln("is_array2(frm_doc2)="+is_array2(frm_doc2)+"<br/>");
document.writeln("Array.isArray(frm_doc2)="+Array.isArray(frm_doc2)+"<br/>");

/*
実行結果

frm_doc[0]=1
frm_doc[1]=2
frm_doc[2]=demon-uploader
frm_doc[3]=2014
frm_doc[4]=true

is_array(frm_doc)=false
is_array2(frm_doc)=true
Array.isArray(frm_doc)=true

frm_doc2[0]=kyoshiro
frm_doc2[1]=demon-uploader
frm_doc2[2]=false
frm_doc2[3]=2014

is_array(frm_doc2)=false
is_array2(frm_doc2)=true
Array.isArray(frm_doc2)=true

*/
</script>
</body>
</html>

```


```javascript:ウインドウで生成された配列がis_array関数でfalse、is_array2関数とArray.isArray関数でtrueになるサンプル
var is_array = function (value) {
return value && typeof value === 'object' && value.constructor === Array;
};

var is_array2 = function (value) {
    return value && 
           typeof value === 'object' && 
           typeof value.length === 'number' && 
           typeof value.splice === 'function' && !(value.propertyIsEnumerable('length'));
};

if(!Array.isArray) {  
  Array.isArray = function (vArg) {  
    return Object.prototype.toString.call(vArg) === "[object Array]";  
  };
}

var frm_doc3 = window.open('http://www.yahoo.co.jp/', '', 'width=800,height=500').Array("kyoshiro","demon-uploader",false, 2014);

document.writeln("<br/>");
document.writeln("frm_doc3[0]="+frm_doc3[0]+"<br/>");
document.writeln("frm_doc3[1]="+frm_doc3[1]+"<br/>");
document.writeln("frm_doc3[2]="+frm_doc3[2]+"<br/>");
document.writeln("frm_doc3[3]="+frm_doc3[3]+"<br/>");
document.writeln("<br/>");
document.writeln("is_array(frm_doc3)="+is_array(frm_doc3)+"<br/>");
document.writeln("is_array2(frm_doc3)="+is_array2(frm_doc3)+"<br/>");
document.writeln("Array.isArray(frm_doc3)="+Array.isArray(frm_doc3)+"<br/>");
document.writeln("<br/>");

/*
実行結果

frm_doc3[0]=kyoshiro
frm_doc3[1]=demon-uploader
frm_doc3[2]=false
frm_doc3[3]=2014

is_array(frm_doc3)=false
is_array2(frm_doc3)=true
Array.isArray(frm_doc3)=true

*/
```

##解説
Javascript Good Partsには、オブジェクトと配列を見分ける関数としてis_array関数が載っている。 __is_arrayは、異なるグローバルオブジェクト(ウインドウやフレームなど)で作成された配列を見分けることができない。
外部からもたらされた配列を判別したい場合is_array2を使う__とある。
※便宜的にis_array2とここでは書いているが、Good Partsではis_array2という名前の関数は掲載されていない。

 __「異なるグローバルオブジェクト(ウインドウやフレームなど)で生成された配列」__ とはどんなものなのか？
この記事では、フレームで生成された配列がis_array関数でfalse、is_array2関数でtrueになるサンプルを書いておきます。
ウインドウで生成された配列ってのは何か分かりません。誰か教えてください。

###追記###
@hikaru_oaoさんの教えてもらいました「ウインドウで生成された配列」はwindow.openで生成された配列ということなので、「ウインドウで生成された配列がis_array関数でfalse、is_array2関数でtrueになるサンプル」を追加しました。

###追記2###
配列とオブジェクトを判定するには、現在ではArray.isArray関数を使うということなので、フレームで生成された配列とウインドウで生成された配列がArray.isArray関数でtrueになることを確認しました。

##

##参考文献
Douglas Crockford 著 水野貴明 訳『JavaScript:The Good Parts』(オライリー・ジャパン発行、2008) p70-71
[Array.isArray() - JavaScript - Mozilla Developer Network][1]

[1]:https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray