2009-05-17 5 views
87

次の二つの異なるコード・スニペットは、私には同等のようだ:配列とオブジェクトの違いは何ですか?

var myArray = Array(); 
myArray['A'] = "Athens"; 
myArray['B'] = "Berlin"; 

var myObject = {'A': 'Athens', 'B':'Berlin'}; 

彼らは両方とも同じように動作し、またtypeof(myArray) == typeof(myObjects)(両方の利回り「オブジェクト」)ので。

これらの亜種には違いがありますか?

答えて

107

JavaScriptで事実上すべてのものがオブジェクトであるので、あなたはそれに任意のプロパティを設定することにより、Arrayオブジェクトを「虐待」することができます。これはshould be considered harmfulです。配列は数値索引付きのデータ用です。非数値キーの場合はObjectを使用します。 - 事実上、何の要素が行われていない

var myArray = Array(); 
myArray['A'] = "Athens"; 
myArray['B'] = "Berlin"; 

alert(myArray.length); 

これは「2」表示するが、「0」ではないでしょう:非数字キーが配列を「適合」していない理由はここに

は、より具体的な例です配列に追加されたばかりの新しいプロパティが配列オブジェクトに追加されました。

+2

myArray.lengthは配列内の最後の要素の数値インデックス/キーを返しますが、実際の要素数は返しません。 Arrayオブジェクトのプロパティは配列値と同じではありませんか? –

+1

Arrayオブジェクトの意図されたセマンティクスを説明しようとしていたのは、通常のオブジェクトのように扱うだけの場合、乱用されていることです。リンクされた記事はより良い仕事をします:) –

+5

次回は誰かがJavaScriptを開発するのに良い言語だと言ったら、私は彼にこのサンプルを示します。ありがとうございました。 –

-1

{} -notationはコードよりよい;-)

JavaScriptは関数は()

var Func = new Function("<params>", "<code>"); 
のためだけの同義語である機能の構築、などの多くの同様の構造を持つようにするだけの構文糖であります
+3

Functionコンストラクタは、関数リテラルのための**はありません**同義語です。リテラルは、コンストラクタがグローバルなときに字句的にスコープされます。 '{}'はリテラルのオブジェクト表記であり、 '[]'はリテラル配列であり、あなたの答えのポイントは何か分かりません。 –

+0

また、宣言された関数は、コードが実行される前に利用可能です。関数コンストラクタを使用する代入は、それらを作成するコードが実行されるまで利用できません。 – RobG

13

JS配列はオブジェクトで、わずかに変更されています(いくつかの機能が追加されています)。

のような機能:

concat 
every 
filer 
forEach 
join 
indexOf 
lastIndexOf 
map 
pop 
push 
reverse 
shift 
slice 
some 
sort 
splice 
toSource 
toString 
unshift 
valueOf 
+0

私は、リストされた関数のすべてがJSの実装ごとに組み込まれているとは思えませんが、あなたはその点を知っています。もう1つの違いは、異なるプロトタイプ(これらの追加機能によって暗示される)です。 – Rashack

5

JavaScriptのすべてがプリミティブ型以外のオブジェクトです。

var myObject = {'A': 'Athens', 'B':'Berlin'}; 

は、オブジェクト、オブジェクトのインスタンスを作成しながら

コード

var myArray = Array(); 

は、Arrayオブジェクトのインスタンスを作成します。

ですから、差がオブジェクトコンストラクタのタイプであるが表示されます、次のコード

alert(myArray.constructor) 
alert(myObject.constructor) 

を試してみてください。

Arrayオブジェクトのインスタンスには、Arrayプロトタイプのすべてのプロパティとメソッドが含まれます。

4

私はあまりにも比喩的で、以前の答えではわかりません。明確化が続く。

Array、Boolean、Date、Function、Number、RegExp、Stringのインスタンスはオブジェクトですが、各タイプに固有のメソッドとプロパティで強化されています。たとえば、配列には事前定義されたlengthプロパティがありますが、汎用オブジェクトにはプロパティはありません。

javascript:alert([].length+'\n'+{}.length) 

ディスプレイ

 
0 
undefined 

は本質的に、FFのGeckoインタプリタはまた、配列や言語構造を評価する明確な違いを持つ汎用オブジェクトを区別します。

javascript: 
    ra=[ "one", "two", "three"]; ra.a=4; 
    ob={0:"one", 1:"two", 2:"three"}; ob.a=4; 
    alert(
    ra   +"\n\n"+ 
    ob   +"\n\n"+ 
    ra.toSource() +"\n\n"+ 
    ra.a   +"\t .toSource() forgot me! \n\n"+ 
    ra.length  +"\t and my length! \n\n"+ 
    ob.toSource()); 
    ps=""; for(i in ra)ps+=i+" "; alert(ps); /* NB .length is missing! */ 
    ps=""; for(i in ob)ps+=i+" "; alert(ps); 

表示

 
one,two,three 

[object Object] 

["one", "two", "three"] 

4 .toSource() forgot me! 

3 and my length! 

({0:"one", 1:"two", 2:"three", a:4}) 

0 1 2 a0 1 2 a。すべてのオブジェクトが機能していることを声明に関して

それobj以外の任意のタイプである123()又は"abc"()又は[]()又は{}()又はobj()ような関数などの任意のオブジェクトのインスタンスを使用することも構文的にも意味的に正しいですFunctionなので、任意のオブジェクトINSTANCEはFunctionではありません。しかし、オブジェクトobjとタイプがArray, Boolean, Date, ...の場合、objはどのようにしてArray, Boolean, Date, ...になるのですか? Array, Boolean, Date, ...とは何ですか?すべての場合には

javascript: 
    alert([Array, Boolean, Date, Function, 
       Number, Object, RegExp, String] . join('\n\n')); 

ディスプレイ

function Array() { 
    [native code] 
} 

function Boolean() { 
    [native code] 
} 

function Date() { 
    [native code] 
} 

function Function() { 
    [native code] 
} 

function Number() { 
    [native code] 
} 

function Object() { 
    [native code] 
} 

function RegExp() { 
    [native code] 
} 

function String() { 
    [native code] 
} 

、曖昧せずに、オブジェクト型はfunction定義、すべてのオブジェクトが機能していること、したがって文として現れます! (私は意図的にオブジェクトインスタンスとそのオブジェクトタイプの区別をあいまいにしてぼかしていました!しかし、これは「他のオブジェクトとオブジェクトを持たないことはできません」ということです。インスタンスとは反対。)

両方の官能オブジェクトパラダイムは、プログラミングの基礎と内蔵例えばMathJSONtrueとしてプリミティブ、JSインタプリタ低レベルの実装であると思われます。

javascript:alert([Math, JSON, true.toSource()].join("\n\n")); 

ディスプレイ

[object Math] 

[object JSON] 

(new Boolean(true)) 

のJavascriptの開発時には、オブジェクト中心のプログラミングスタイル(OOPの - オブジェクト指向プログラミングのスタイル - 「さんは、」私自身のしゃれです!)が流行し、通訳者は同様にJavaに洗礼をかけて信頼性を高めました。機能的プログラミング技法は、オートマタ、再帰関数、形式言語などの理論を研究するような、抽象的で難解な試験に委ねられた。しかし、これらの正式な考慮事項の強みは、特にFFのGeckoエンジン(すなわち、.toSource())に実装されているように、Javascriptでは明白に現れています。


Functionのオブジェクト定義は、特にそれが漸化関係として定義されているため満足です!それ自身の定義を使って定義されています!

function Function() { [native code] }
と機能が同じ感情が
function Object() { [native code] }ために保持するオブジェクトであるからです。

他の定義のほとんどは、静的なターミナル値を静止します。しかし、eval()は特に強力なプリミティブであるため、Stringは任意の機能を組み込むこともできます。

ここでも、上記で使用された母国語は、オブジェクトの種類とインスタンスの区別を覆い隠しています。

1

一つの実用的な違いarrayJSON.stringifyを使用している場合、すべての非数値インデックスは無視されます。

var arr = []; 
var obj = {}; 

arr['name'] = 'John'; 
obj['name'] = 'John'; 

console.log(arr); // will output [name: "John"] 
console.log(obj); // will output {name: "John"} 

JSON.stringify(arr); // will return [] 
JSON.stringify(obj); // will return {"name":"John"} 
関連する問題