Array associativi in JavaScript

Gli array sono probabilmente le strutture piu utilizzate in JavaScript. I vantaggi sono molteplici: tramite gli array possiamo definire strutture di dati, parametrizzare le pagine, memorizzare settaggi e configurazioni prodotti dai linguaggi di programmazione server-side. Nonostante la loro popolarita, a volte la conoscenza degli array rimane superficiale. E normale utilizzare gli array solamente come struttura di dati, senza sfruttare a fondo le potenzialita di JavaScript, come ad esempio il prototyping, la gestione dinamica della dimensione oppure gli array associativi.

Gli array sono probabilmente le strutture più utilizzate in JavaScript. I vantaggi sono molteplici: tramite gli array possiamo definire strutture di dati, parametrizzare le pagine, memorizzare settaggi e configurazioni prodotti dai linguaggi di programmazione server-side. Nonostante la loro popolarità, a volte la conoscenza degli array rimane superficiale. È normale utilizzare gli array solamente come struttura di dati, senza sfruttare a fondo le potenzialità di JavaScript, come ad esempio il prototyping, la gestione dinamica della dimensione oppure gli array associativi. Oggi cercheremo di chiarire caratteristiche e funzionamento degli array associativi. Prima di iniziare, è d’uopo un breve ripasso introduttivo delle nozioni di base degli array JavaScript. Una prima caratteristica non sempre nota è la possibilità di indicizzare gli array in modo dinamico. Consideriamo ad esempio

dove abbiamo ipotizzato l’utilizzo della console di Firebug come strumento di debug: se non usiamo Firefox, un normale

JavaScript andrà benissimo. L’esempio mostra come la dimensione dell’array risulta automaticamente aggiornata dopo l’aggiunta di ogni elemento: quando definiamo il primo elemento (i.e. 10), di indice zero, la lunghezza dell’array diventa 1. Subito dopo, quando aggiungiamo il secondo elemento (i.e. 20), la lunghezza dell’array assume valore 2. Altre caratteristiche da ricordare sono: la possibilità di memorizzare dati eterogenei all’interno dello stesso array (stringhe, numeri, oggetti ecc.), la sintassi abbreviata di creazione degli array (ad esempio foo = [1, 2]), ed infine la possibilità di avere array soltanto parzialmente popolati. Ciò significa, in particolare, che la lunghezza dell’array è generalmente maggiore del numero di elementi esplicitamente definiti al suo interno. Ad esempio

nell’esempio sopra abbiamo un array di lunghezza pari a 4, che però contiene solamente due elementi ben definiti. Gli elementi di indice 0 e 2 risultano undefined. Ciò significa che non è possibile distinguere, in base al valore, un elemento non definito da un elemento non presente nell’array. In parole più semplici, gli elementi

e

sono entrambi undefined, indipendentemente da quella che è lunghezza dell’array.

array_02

Array associativi

Array associativi

Dopo aver ripassato i concetti fondamentali degli array JavaScript, passiamo all’utilizzo e definizione degli array associativi. Un esempio potrebbe essere

l’array si dice associativo perché al posto dell’indice numerico adesso abbiamo una chiave alfanumerica, qui sopra pari a “js” e “css”. In questo caso è utile rispettare la nomenclatura ufficiale: chiamiamo chiavi le stringhe che prendono il posto degli indici, e valori gli elementi associati alle chiavi. La terminologia è usata in parecchi paradigmi di programmazione, come ad esempio C, Java o PHP. In molti casi una struttura come questa è chiamata mappa o hashmap, ed è caratterizzata dalle coppie chiave-valore, come nell’esempio qui sopra.

Il primo vantaggio degli array associativi è la maggior leggibilità del codice, ovvero la possibilità di recuperare in modo intuitivo i valori che ci interessano, specie se utilizziamo etichette adeguate come chiavi degli elementi. Ciò permette, ad esempio, di usare un array per mappare i risultati di una query SQL, oppure le proprietà dell’oggetto nell’ambito del paradigma OOP. Gli array associativi hanno però caratteristiche che possono confondere chi si appresta ad usarli per la prima volta

  • Non è possibile visualizzarne il contenuto usando un banale alert. Gli elementi dell’array associativo sono trattati del motore JavaScript come le proprietà di un oggetto: è necessario scorrere gli elementi uno per uno, usando le rispettive chiavi, per visualizzare il contenuto dell’array
  • Il valore ritornato dalla proprietà length è sempre zero, per lo stesso motivo sopra: trattandosi dell’oggetto non ha in generale senso parlare della sua lunghezza

Un modo semplice di scorrere il contenuto di un array associativo sfruttando la sintassi alternativa del ciclo for è il seguente

nel caso qui sopra, la variabile i assume automaticamente tutte le possibili chiavi presenti nell’array. Considerando l’array definito più sopra, al primo ciclo la variabile i vale “js”, mentre secondo ciclo essa assume il valore “css”. Il ciclo qui sopra è lo stesso che viene utilizzato per visualizzare le proprietà di un oggetto JavaScript. È una coincidenza, o esiste un motivo ben preciso? Ovviamente non si tratta di una coincidenza: se possiamo scorrere i valori di un array esattamente come le proprietà dell’oggetto, significa che gli array associativi sono in realtà una sorta di API alternativa per accedere agli oggetti JavaScript. Per verificarlo basta provare il codice qui sotto

Il risultato è identico a quello trovato sopra: possiamo definire la chiave “css” sia usando la notazione degli array, sia la sintassi relativa alle proprietà degli oggetti. Questo spiega le “stranezze” discusse prima: trattandosi di normali oggetti JavaScript, gli array associativi non hanno lunghezza e vanno analizzati usando la sintassi specifica degli oggetti. Un modo di verificare se abbiamo compreso il concetto, è provare a definire l’array usando un oggetto.

In ogni caso, per evitare confusione, è bene utilizzare la sintassi degli array, per rendere più leggibile il codice e facilitare le operazioni di manutenzione.

Conclusioni

Conclusioni

Una volta compreso il funzionamento degli array associativi, possiamo chiederci se e quando vale la pena usarli. Dagli esempi precedenti deduciamo che non esiste alcuna differenza sostanziale tra array associativi e oggetti JavaScript. Ciò è corretto, perché gli array di fatto estendono gli oggetti. Da questo punto di vista in molti casi è meglio evitare di usare gli array associativi, ricorrendo invece ai normali oggetti JavaScript. Possiamo ottenere gli stessi risultati delle pagine precedenti scrivendo semplicemente

come al solito, tutto dipende da ciò che dovevo fare. Se abbiamo bisogno di una struttura dati dove organizzare informazioni, nella maggior parte dei casi risulta più comodo definire un oggetto opportuno, definendo tutti i campi e metodi che ci servono. Viceversa, se dobbiamo memorizzare una semplice matrici dati, ovvero un array bidimensionale, allora può risultare utile ricorrere agli array associativi. Un caso tipico potrebbe essere

che potrebbe rappresentare il risultato di una query nel database. Altre variabili di cui tener conto, nella scelta tra array e oggetti, sono la densità e tipologia delle chiavi della struttura dati. Ecco perché, prima di mettere mano al codice, è sempre bene eseguire uno studio o valutazione preliminare. Se la sequenza di chiavi attesa è una normale sequenza numerica ordinata, in molti casi tanto vale usare un normale array, ovvero un array non associativo. Se il codice deve essere facilmente leggibile, oppure vogliamo assegnare le chiavi a run-time, in modo semplice e veloce, allora va benissimo un array associativo. Infine, se la struttura dati è una buona candidata per essere riutilizzata nel codice, spesso è bene definire delle classi di oggetti e lavorare nell’ambito del paradigma OOP. Queste sono, a nostro parere, le variabili principali che dovrebbero orientarci nella decisione. Dal punto di vista delle performance, poiché ogni array è alla fin fine un oggetto JavaScript, non vi è una differenza sostanziale. Ecco perché il criterio più importante dovrebbe essere il business model delle strutture dati, ovvero il modello che riteniamo più adeguato a descrivere le entità trattate dal codice.