web-dev-qa-db-ja.com

オブジェクトを含むtypeof配列が「配列」ではなく「オブジェクト」を返すのはなぜですか?

可能性のある複製:
JavaScript:オブジェクトが配列かどうかを確認しますか?

オブジェクトの配列が、配列ではなくオブジェクトと見なされるのはなぜですか?例えば:

$.ajax({
    url: 'http://api.Twitter.com/1/statuses/user_timeline.json',
    data: { screen_name: 'mick__romney'},
    dataType: 'jsonp',
    success: function(data) {
        console.dir(data); //Array[20]
        alert(typeof data); //Object
    }
});​

フィドル

115
Johan

Javascriptの奇妙な動作と仕様の1つは、typeof配列がObjectです。

変数が配列であるかどうかを確認するには、いくつかの方法があります。

var isArr = data instanceof Array;
var isArr = Array.isArray(data);

しかし、最も信頼できる方法は次のとおりです。

isArr = Object.prototype.toString.call(data) == '[object Array]';

JQueryで質問にタグを付けたので、jQuery isArray 関数を使用できます。

var isArr = $.isArray(data);
206
gdoron

仕様を引用する

15.4配列オブジェクト

配列オブジェクトは、特定のクラスのプロパティ名に特別な処理を提供します。 ToString(ToUint32(P))がPに等しく、ToUint32(P)が2 ^ 32-1に等しくない場合にのみ、プロパティ名P(文字列値の形式)は配列インデックスです。プロパティ名が配列インデックスであるプロパティは、要素とも呼ばれます。すべてのArrayオブジェクトには、値が常に2 ^ 32未満の非負整数であるlengthプロパティがあります。 lengthプロパティの値は、名前が配列インデックスであるすべてのプロパティの名前よりも数値的に大きいです。 Arrayオブジェクトのプロパティが作成または変更されるたびに、この不変式を維持するために必要に応じて他のプロパティが調整されます。具体的には、名前が配列インデックスであるプロパティが追加されるたびに、必要に応じて長さプロパティが変更され、その配列インデックスの数値よりも1つ大きくなります。また、長さプロパティが変更されるたびに、名前が新しいインデックスよりも小さくない値を持つ配列インデックスであるすべてのプロパティが自動的に削除されます。この制約は、Arrayオブジェクトの独自のプロパティにのみ適用され、プロトタイプから継承される可能性のある長さまたは配列インデックスのプロパティの影響を受けません。

そして、これはtypeofの表です

enter image description here


背景を追加するために、JavaScriptには2つのデータ型があります。

  1. Primitive Data types-これには、null、undefined、string、boolean、number、およびobjectが含まれます。
  2. 派生データ型/特殊オブジェクト-関数、配列、正規表現が含まれます。はい、これらはすべてJavaScriptの「オブジェクト」から派生しています。

JavaScriptのオブジェクトは、ほとんどのオブジェクト指向言語で見られる連想配列/辞書と構造が似ています。つまり、キーと値のペアのセットがあります。

配列は、次のプロパティ/キーを持つオブジェクトと見なすことができます。

  1. 長さ-0以上の値(負でない)を指定できます。
  2. 配列のインデックス。つまり、「0」、「1」、「2」などはすべて配列オブジェクトのプロパティです。

これがtypeof Arrayがオブジェクトを返す理由をさらに明らかにするのに役立つことを願っています。乾杯!

23
Prinzhorn

この例を試してみると、JavaScriptの連想配列とオブジェクトの違いも理解できます。

連想配列

var a = new Array(1,2,3); 
a['key'] = 'experiment';
Array.isArray(a);

trueを返します

lengthはキーとして扱われるため、a.lengthは未定義になることに注意してください。連想配列の長さを取得するには、Object.keys(a).lengthを使用する必要があります。

オブジェクト

var a = {1:1, 2:2, 3:3,'key':'experiment'}; 
Array.isArray(a)

falseを返します

JSONはObjectを返します...連想配列を返します...が、そうではありません

6
Reflective