2009-05-17 24 views
87

I seguenti due diversi frammenti di codice sembrano equivalenti a me:Qual è la differenza tra un array e un oggetto?

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

e

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

perché entrambi si comportano allo stesso, e anche typeof(myArray) == typeof(myObjects) (sia resa 'oggetto').

C'è qualche differenza tra queste varianti?

risposta

107

Praticamente tutto in JavaScript è un oggetto, in modo da poter "abuso" di un Array oggetto impostando le proprietà arbitrarie su di esso. Questo should be considered harmful però. Le matrici sono per i dati indicizzati numericamente - per le chiavi non numeriche, utilizzare un oggetto.

Ecco un esempio più concreto perché i tasti non numerici non "fit" di un array:

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

alert(myArray.length); 

Questo non visualizzerà '2', ma '0' - in modo efficace, senza elementi sono stati aggiunto all'array, solo alcune nuove proprietà aggiunte all'oggetto array.

+2

myArray.length restituisce un indice/chiave numerica dell'ultimo elemento nella matrice ma non il numero effettivo di elementi. Le proprietà dell'oggetto Array non sono uguali ai valori dell'array? –

+1

Stavo solo cercando di illustrare la semantica voluta dell'oggetto Array che viene abusato se lo tratti come un normale oggetto. L'articolo collegato fa un lavoro migliore però :) –

+5

La prossima volta che qualcuno dice che JavaScript è un buon linguaggio con cui svilupparlo, gli mostrerò questo esempio. Grazie. –

-1

Il {} -notation è lo zucchero solo sintattica per rendere il codice più bello ;-)

JavaScript ha molti costrutti simili come la costruzione di funzioni, in cui la funzione() è solo un sinonimo di

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

costruttore La funzione è ** non ** un sinonimo per la funzione letterale. Il letterale è con validità lessicale mentre il costruttore è globale. '{}' è letterale notazione oggetto, '[]' è array letterale, non sono sicuro di quale sia il punto della tua risposta. –

+0

Inoltre, le funzioni dichiarate sono disponibili prima dell'esecuzione di qualsiasi codice, le assegnazioni che utilizzano la funzione di costruzione Funzione non sono disponibili finché non viene eseguito il codice che le crea. – RobG

13

Negli array JS gli oggetti sono solo leggermente modificati (con alcune funzioni in più).

funzioni come:

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

Anche se non penso che tutte le funzioni elencate siano integrate in ogni implementazione JS, hai capito il punto. L'altra differenza sarebbe un diverso prototipo (che è implicito da quelle funzioni extra). – Rashack

5

Tutto in JavaScript è un oggetto oltre ai tipi primitivi.

Il codice

var myArray = Array(); 

crea un'istanza dell'oggetto Array mentre

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

crea un'istanza di oggetto oggetto.

provare il seguente codice

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

Quindi, si vedrà la differenza è nel tipo di costruttore dell'oggetto.

L'istanza dell'oggetto Array conterrà tutte le proprietà e i metodi del prototipo di matrice.

4

Mi crede, anch'io metaforico e criptico con la risposta precedente. Il chiarimento segue.

Un'istanza di Array, Boolean, Date, Function, Number, RegExp, String è un oggetto ma arricchito con metodi e proprietà specifici per ciascun tipo. Ad esempio, un array ha una proprietà predefinita length mentre gli oggetti generici no.

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

display

 
0 
undefined 

intrinseca, l'interprete FF Gecko distingue inoltre tra array e oggetti generici con differenze distinte valutano costrutti linguistici.

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

visualizzazione

 
one,two,three 

[object Object] 

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

4 .toSource() forgot me! 

3 and my length! 

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

e 0 1 2 a e 0 1 2 a.

quanto riguarda la situazione che tutti gli oggetti sono funzioni:

Non è né sintatticamente né semanticamente corretto utilizzare un'istanza oggetto arbitrario come una funzione come 123() o "abc"() o []() o {}() o obj() dove obj è un tipo diverso da Function, quindi un oggetto arbitrario INSTANCE non è un Function. Tuttavia, dato un oggetto obj ed è tipo come Array, Boolean, Date, ..., come è stato obj come Array, Boolean, Date, ...? Che cos'è un Array, Boolean, Date, ...?

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

display

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 ogni caso, senza equivoci, il tipo di oggetto manifesta come una definizione function, quindi l'affermazione che tutti gli oggetti sono funzioni! (La lingua scherzata è che ho intenzionalmente oscurato e offuscato la distinzione di un'istanza di oggetto con quella del suo tipo! Tuttavia, questo mostra "non puoi averne uno senza l'altro", Oggetto e funzione! oppongono esempio.)

sia un paradigma funzionale ed oggetto sembrano essere fondamentale per la programmazione e l'attuazione delle primitive incorporate JS interprete basso livello, come Math e JSON e true.

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

display

[object Math] 

[object JSON] 

(new Boolean(true)) 

Al momento dello sviluppo di Javascript, uno stile di programmazione object-centric (di OOP - Object Oriented stile di programmazione - la "s '" è il mio gioco di parole !) era in voga e l'interprete è stato similmente battezzato con Java per dargli maggiore credibilità. Le tecniche di programmazione funzionale sono state relegate a esami più astratti ed esoterici studiando le teorie degli automi, delle funzioni ricorsive, delle lingue formali, ecc. E in quanto tali non sono accettabili. Tuttavia, i punti di forza di queste considerazioni formali si manifestano chiaramente in Javascript, in particolare come implementate nel motore Gecko di FF (ad esempio .toSource()).


La definizione oggetto per la funzione è particolarmente soddisfacente per esso è definito come una relazione di ricorrenza! definito utilizzando la propria definizione!

function Function() { [native code] }
e dal momento che una funzione è un oggetto lo stesso sentimento vale per
function Object() { [native code] }.

La maggior parte delle altre definizioni è sospesa su un valore di terminale statico. Tuttavia, eval() è una primitiva particolarmente potente e quindi una stringa può anche incorporare funzionalità arbitrarie.

Nota ancora, il vernacolo usato sopra oscura il tipo di oggetto e la distinzione di istanza.

1

Una differenza pratica è quando si utilizza JSON.stringify su un array tutti non numerico indici vengono ignorati:

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"} 
Problemi correlati