2009-05-17 18 views
87

Die folgenden zwei verschiedenen Code-Schnipsel scheinen mir äquivalent:Was ist der Unterschied zwischen einem Array und einem Objekt?

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

und

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

, weil sie beide gleich verhalten, und auch typeof(myArray) == typeof(myObjects) (beide Ausbeute 'Objekt').

Gibt es einen Unterschied zwischen diesen Varianten?

Antwort

107

Praktisch alles, was in JavaScript ein Objekt ist, so können Sie „Missbrauch“ ein Array Objekt durch beliebige Eigenschaften auf sie einstellen. Diese should be considered harmful obwohl. Arrays sind für numerisch indizierte Daten - für nicht-numerische Schlüssel verwenden Sie ein Objekt.

Hier ist ein konkreteres Beispiel, warum nicht-numerische Tasten ein Array nicht „fit“:

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

alert(myArray.length); 

Dies wird nicht angezeigt ‚2‘, sondern ‚0‘ - effektiv sind keine Elemente gewesen Zum Array hinzugefügt wurden nur einige neue Eigenschaften zum Array-Objekt hinzugefügt.

+2

myArray.length gibt einen numerischen Index/Schlüssel des letzten Elements im Array zurück, aber nicht die tatsächliche Anzahl der Elemente. Sind Eigenschaften des Array-Objekts nicht dieselben wie Array-Werte? –

+1

Ich habe gerade versucht zu veranschaulichen, die beabsichtigte Semantik des Array-Objekts missbraucht werden, wenn Sie es einfach wie ein normales Objekt behandeln. Der verlinkte Artikel macht aber einen besseren Job :) –

+5

Das nächste Mal, wenn jemand sagt, dass JavaScript eine gute Sprache ist, mit der ich mich weiterentwickle, zeige ich ihm dieses Beispiel. Vielen Dank. –

-1

Die {} -Notation ist nur syntaktischer Zucker den Code schöneres ;-)

JavaScript hat viele ähnlichen Konstrukte wie die Konstruktion von Funktionen zu machen, wobei die Funktion() ist nur ein Synonym für

var Func = new Function("<params>", "<code>"); 
+3

Funktion Konstruktor ** NICHT ** ein Synonym für die Funktionsliteral. Das Literal ist lexikalisch begrenzt, während der Konstruktor global ist. '{}' ist eine literale Objektnotation, '[]' ist ein literales Array, ich bin nicht sicher, was der Punkt Ihrer Antwort ist. –

+0

Auch deklarierte Funktionen sind verfügbar, bevor ein Code ausgeführt wird. Zuordnungen, die den Konstruktor Function verwenden, sind erst verfügbar, wenn der Code, der sie erstellt, ausgeführt wird. – RobG

13

In JS-Arrays sind Objekte, nur leicht modifiziert (mit ein paar mehr Funktionen).

Funktionen wie:

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

Obwohl ich glaube nicht, dass alle aufgeführten Funktionen in jeder JS-Implementierung integriert sind, haben Sie den Punkt verstanden. Der andere Unterschied wäre ein anderer Prototyp (was durch diese zusätzlichen Funktionen impliziert wird). – Rashack

5

Alles in JavaScript ist ein Objekt neben primitiven Typen.

Der Code

var myArray = Array(); 

erzeugt eine Instanz des Objekts, während Array

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

eine Instanz-Objekt-Objekt erzeugt.

Versuchen Sie den folgenden Code

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

So sehen Sie den Unterschied in der Art des Objektkonstruktor ist.

Die Instanz des Array-Objekts enthält alle Eigenschaften und Methoden des Array-Prototyps.

4

Ich denke, ich auch metaphorisch und kryptisch mit vorheriger Antwort. Erläuterung folgt.

Eine Instanz von Array, Boolean, Datum, Funktion, Zahl, RegExp, String ist ein Objekt, aber mit spezifischen Methoden und Eigenschaften für jeden Typ erweitert. Zum Beispiel hat ein Array eine vordefinierte length Eigenschaft, während generische Objekte dies nicht tun.

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

Displays

 
0 
undefined 

Eigen unterscheidet die FF Gecko-Interpreter auch zwischen Arrays und generischen Objekten mit deutlichen Unterschieden Sprachkonstrukte zu bewerten.

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); 

Anzeigen

 
one,two,three 

[object Object] 

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

4 .toSource() forgot me! 

3 and my length! 

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

und 0 1 2 a und 0 1 2 a.

Die Aussage betreffend, dass alle Objekte sind Funktionen:

Es ist weder syntaktisch noch semantisch korrekt andere eine beliebige Objektinstanz als eine Funktion wie 123() oder "abc"() oder []() oder {}() oder obj() wo obj ist jede Art zu verwenden, als Function, so ein beliebiges Objekt INSTANCE ist kein Function. Jedoch, wenn ein Objekt obj und sein Typ wie Array, Boolean, Date, ... gegeben wird, wie ist obj zu einem Array, Boolean, Date, ... geworden? Was ist ein Array, Boolean, Date, ...?

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

Displays

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] 
} 

In jedem Fall ohne Zweideutigkeit, manifestiert sich der Objekttyp als function Definition, damit die Aussage, dass alle Objekte Funktionen sind! (Die augenzwinkernde ist, dass ich absichtlich die Unterscheidung einer Objektinstanz mit der ihres Typs verdunkelt und verschwommen habe! Dennoch zeigt dies, "Sie können keine ohne die andere haben", Objekt und Funktion! Großschreibung betont Typ als im Gegensatz zu ein.)

Sowohl ein funktionales Objekt und Paradigma der Programmierung zu sein scheinen grundlegende und Umsetzung der Interpreter JS niedrigen Pegel Einbau-Primitiven wie Math und JSON und true.

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

Displays

[object Math] 

[object JSON] 

(new Boolean(true)) 

Zum Zeitpunkt der Entwicklung von Javascript, ein Objekt-zentrierte Programmierstil (OOP ist - Programmierung Stil Oriented Object - das "s" mein eigenes Wortspiel ist !) war in Mode und der Interpreter wurde in ähnlicher Weise mit Java getauft, um es glaubwürdiger zu machen. Funktionale Programmiertechniken wurden auf abstraktere und esoterische Untersuchungen beschränkt, die die Theorien von Automaten, rekursiven Funktionen, formalen Sprachen usw. untersuchten und daher nicht so schmackhaft waren. Die Stärken dieser formalen Überlegungen zeigen sich jedoch deutlich in Javascript, insbesondere in FFs Gecko-Engine (z. B. .toSource()).


Die Objektdefinition für Funktion ist besonders befriedigend, da sie als Rekursionsbeziehung definiert ist! definiert mit eigener Definition!

function Function() { [native code] }
und da eine Funktion ist ein Objekt das gleiche Gefühl für
function Object() { [native code] } hält.

Die meisten anderen Definitionen werden auf einen statischen Endwert gesetzt. Allerdings ist eval() ein besonders leistungsfähiges Primitiv und so kann ein String auch beliebige Funktionalität einbetten.

Beachten Sie erneut, dass die oben verwendete Umgangssprache den Objekttyp und die Instanzunterscheidung verdeckt.

1

Ein praktischer Unterschied ist, wenn JSON.stringify Verwendung auf ein array alle nicht-numerische Indizes ignoriert werden:

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"} 
Verwandte Themen