034.2 Lezione 1
Certificazione: |
Web Development Essentials |
---|---|
Versione: |
1.0 |
Argomento: |
034 Programmazione JavaScript |
Obiettivo: |
034.2 Strutture di Dati in JavaScript |
Lezione: |
1 di 1 |
Introduzione
I linguaggi di programmazione, come i linguaggi naturali, rappresentano la realtà attraverso simboli che sono combinati in dichiarazioni significative. La realtà rappresentata da un linguaggio di programmazione sono le risorse della macchina, come le operazioni del processore, i dispositivi e la memoria.
Ognuno della miriade di linguaggi di programmazione adotta un paradigma per rappresentare le informazioni. JavaScript adotta convenzioni tipiche dei linguaggi di alto livello, dove la maggior parte dei dettagli come l’allocazione della memoria sono impliciti, permettendo al programmatore di concentrarsi sullo scopo dello script nel contesto dell’applicazione.
Linguaggi di Alto Livello
I linguaggi di alto livello forniscono regole astratte in modo che il programmatore abbia bisogno di scrivere meno codice per esprimere un’idea. JavaScript offre modi convenienti per fare uso della memoria del computer, utilizzando concetti di programmazione che semplificano la scrittura di pratiche ricorrenti e che sono generalmente sufficienti per lo scopo dello sviluppatore web.
Note
|
Anche se è possibile utilizzare meccanismi specializzati per un accesso meticoloso alla memoria, i tipi di dati più semplici che vedremo sono di uso più generale. |
Le operazioni tipiche in un’applicazione web consistono nel richiedere dati attraverso qualche istruzione JavaScript e nel memorizzarli per essere elaborati ed eventualmente presentati all’utente. Questa memorizzazione è abbastanza flessibile in JavaScript, con formati di memorizzazione adatti a ogni scopo.
Dichiarazione di Costanti e Variabili
La dichiarazione di costanti e variabili per contenere dati è la pietra angolare di qualsiasi linguaggio di programmazione. JavaScript adotta la convenzione della maggior parte dei linguaggi di programmazione, assegnando valori a costanti o variabili con la sintassi nome = valore
. La costante o la variabile a sinistra prende il valore a destra. Il nome della costante o della variabile deve iniziare con una lettera o un underscore.
Il tipo di dati memorizzati nella variabile non ha bisogno di essere indicato, perché JavaScript è un linguaggio a tipizzazione dinamica. Il tipo della variabile viene dedotto dal valore che le viene assegnato. Tuttavia, è conveniente designare certi attributi nella dichiarazione per garantire il risultato atteso.
Note
|
TypeScript è un linguaggio ispirato a JavaScript che, come i linguaggi low_level, permette di dichiarare variabili per specifici tipi di dati. |
Costanti
Una costante è un simbolo che viene assegnato solo una volta all’avvio del programma e non cambia mai. Le costanti sono utili per specificare valori fissi come definire la costante PI
con 3.14159265, o COMPANY_NAME
con il nome della tua azienda.
In un’applicazione web, per esempio, prendiamo un client che riceve informazioni meteorologiche da un server remoto. Il programmatore può decidere che l’indirizzo del server debba essere costante, perché non cambierà durante l’esecuzione dell’applicazione. Le informazioni sulla temperatura, tuttavia, possono cambiare a ogni nuovo arrivo di dati dal server.
L’intervallo tra le interrogazioni fatte al server può anche essere definito come una costante, che può essere interrogata da qualsiasi parte del programma:
const update_interval = 10;
function setup_app(){
console.log("Update every " + update_interval + "minutes");
}
Quando viene invocata, la funzione setup_app()
visualizza il messaggio Update every 10 minutes
sulla console. Il termine const
posto prima del nome update_interval
fa sì che il suo valore rimanga lo stesso durante l’intera esecuzione dello script. Se si tenta di reimpostare il valore di una costante, si verifica un errore: TypeError: Assignment to constant variable
.
Variabili
Senza il termine const
, JavaScript assume automaticamente che update_interval
sia una variabile e che il suo valore possa essere modificato. Questo equivale a dichiarare esplicitamente la variabile con var
:
var update_interval;
update_interval = 10;
function setup_app(){
console.log("Update every " + update_interval + "minutes");
}
Sebbene la variabile update_interval
sia stata definita al di fuori della funzione, vi si accede dall’interno della funzione. Qualsiasi costante o variabile dichiarata al di fuori di funzioni o blocchi di codice definiti da parentesi graffe ({}
) ha uno scopo globale; cioè, vi si può accedere da qualsiasi parte del codice. Attenzione perchè non è vero il contrario: una costante o una variabile dichiarata all’interno di una funzione ha uno scopo locale, quindi è accessibile solo dall’interno della funzione stessa. I blocchi di codice delimitati da parentesi, come quelli inseriti nelle strutture decisionali if
o nei cicli for
, delimitano lo scopo delle costanti, ma non delle variabili dichiarate come var
. Il seguente codice, per esempio, è valido:
var success = true;
if ( success == true )
{
var message = "Transaction succeeded";
var retry = 0;
}
else
{
var message = "Transaction failed";
var retry = 1;
}
console.log(message);
L’istruzione console.log(message) è in grado di accedere alla variabile message
, anche se è stata dichiarata all’interno del blocco di codice della struttura if
. Lo stesso non accadrebbe se message
fosse costante, come esemplificato nell’esempio seguente:
var success = true;
if ( success == true )
{
const message = "Transaction succeeded";
var retry = 0;
}
else
{
const message = "Transaction failed";
var retry = 1;
}
console.log(message);
In questo caso, verrebbe emesso un messaggio di errore del tipo ReferenceError: message is not defined
e lo script verrebbe fermato. Anche se può sembrare una limitazione, restringere lo scopo delle variabili e delle costanti aiuta a evitare la confusione tra le informazioni trattate nel corpo dello script e suoi diversi blocchi di codice. Per questo motivo, le variabili dichiarate con let
invece di var
sono anche limitate nello scopo dai blocchi delimitati da parentesi graffe. Ci sono altre sottili differenze tra dichiarare una variabile con var
o con let
, ma la più significativa riguarda lo “scopo” della variabile, come discusso qui di seguito.
Tipi di Valore
La maggior parte delle volte il programmatore non ha bisogno di preoccuparsi del tipo di dati memorizzati in una variabile, perché JavaScript li identifica automaticamente con uno dei suoi tipi primitivi durante la prima assegnazione di un valore alla variabile. Alcune operazioni, tuttavia, possono essere specifiche per un tipo di dati o un altro e possono provocare errori se usate senza discrezione. Inoltre, JavaScript offre tipi strutturati che permettono di combinare più di un tipo primitivo in un singolo oggetto.
Tipi Primitivi
Le istanze di tipo primitivo corrispondono alle variabili tradizionali, che memorizzano un solo valore. I tipi sono definiti implicitamente, quindi l’operatore typeof
può essere usato per identificare quale tipo di valore è memorizzato in una variabile:
console.log("Undefined variables are of type", typeof variable);
{
let variable = true;
console.log("Value `true` is of type " + typeof variable);
}
{
let variable = 3.14159265;
console.log("Value `3.14159265` is of type " + typeof variable);
}
{
let variable = "Text content";
console.log("Value `Text content` is of type " + typeof variable);
}
{
let variable = Symbol();
console.log("A symbol is of type " + typeof variable);
}
Questo script mostrerà sulla console che tipo di variabile è stata usata in ognuno dei casi:
undefined variables are of type undefined Value `true` is of type boolean Value `3.114159265` is of type number Value `Text content` is of type string A symbol is of type symbol
Nota che la prima linea cerca di trovare il tipo di una variabile non dichiarata. Questo fa sì che la variabile data sia identificata come undefined
. Il tipo symbol
è la primitiva meno intuitiva. Il suo scopo è quello di fornire un nome di attributo unico all’interno di un oggetto quando non c’è bisogno di definire un nome di attributo specifico. Un oggetto è una delle strutture dati che vedremo in seguito.
Tipi Strutturati
Mentre i tipi primitivi sono sufficienti per scrivere semplici routine, ci sono svantaggi nell’usarli esclusivamente in applicazioni più complesse. Un’applicazione di e-commerce, per esempio, sarebbe molto più difficile da scrivere, perché il programmatore dovrebbe trovare il modo di memorizzare liste di articoli e valori corrispondenti usando solo variabili con tipi primitivi.
I tipi strutturati semplificano il compito di raggruppare informazioni della stessa natura in una singola variabile. Una lista di articoli in un carrello della spesa, per esempio, può essere memorizzata in una singola variabile di tipo array:
let cart = ['Milk', 'Bread', 'Eggs'];
Come dimostrato nell’esempio, un array di elementi è contraddistinto da parentesi quadre. L’esempio ha popolato l’array con tre valori letterali di stringa, da cui l’uso delle virgolette singole. Anche le variabili possono essere usate come elementi di un array, ma in questo caso devono essere designate senza virgolette. Il numero di elementi in un array può essere interrogato con la proprietà length
:
let cart = ['Milk', 'Bread', 'Eggs'];
console.log(cart.length);
Il numero 3
sarà visualizzato nell’output della console. Nuovi elementi possono essere aggiunti all’array con il metodo push()
:
cart.push('Candy');
console.log(cart.length);
Questa volta, la cifra visualizzata sarà 4
. Ogni elemento della lista può essere raggiunto tramite il suo indice numerico, a partire da 0
:
console.log(cart[0]);
console.log(cart[3]);
L’output visualizzato sulla console sarà:
Milk Candy
Proprio come è possibile usare push()
per aggiungere un elemento, è anche possibile usare pop()
per rimuovere l’ultimo elemento da un array.
Non è necessario che i valori memorizzati in una matrice siano dello stesso tipo. È possibile, per esempio, memorizzare la quantità di ogni articolo accanto a esso. Una lista della spesa come quella dell’esempio precedente potrebbe essere costruita come segue:
let cart = ['Milk', 1, 'Bread', 4, 'Eggs', 12, 'Candy', 2];
// Item indexes are even
let item = 2;
// Quantities indexes are odd
let quantity = 3;
console.log("Item: " + cart[item]);
console.log("Quantity: " + cart[quantity]);
L’output visualizzato sulla console dopo l’esecuzione di questo codice è:
Item: Bread Quantity: 4
Come avrai già notato, combinare i nomi degli elementi con le loro rispettive quantità in un unico array può non essere una buona idea, perché la relazione tra loro non è esplicita nella struttura dei dati ed è molto suscettibile di errori (umani). Anche se si usasse un array per i nomi e un altro array per le quantità, mantenere l’integrità della lista richiederebbe la stessa cura e non sarebbe molto produttivo. In queste situazioni, l’alternativa migliore è usare una struttura di dati più appropriata: un oggetto.
In JavaScript una struttura di dati di tipo oggetto permette di legare proprietà a una variabile. Inoltre, a differenza di un array, gli elementi che compongono un oggetto non hanno un ordine fisso. Un elemento della lista della spesa, per esempio, può essere un oggetto con le proprietà name
e quantity
:
let item = { name: 'Milk', quantity: 1 };
console.log("Item: " + item.name);
console.log("Quantity: " + item.quantity);
Questo esempio mostra che un oggetto può essere definito usando le parentesi graffe ({}
), dove ogni coppia proprietà/valore è separata da due punti e le proprietà sono separate da virgole. La proprietà è accessibile nel formato variable.property, come in item.name
, sia per la lettura che per l’assegnazione di nuovi valori. L’output visualizzato sulla console dopo l’esecuzione di questo codice è:
Item: Milk Quantity: 1
Infine, ogni oggetto che rappresenta un elemento può essere incluso nell’array della lista della spesa. Questo può essere fatto direttamente quando si crea la lista:
let cart = [{ name: 'Milk', quantity: 1 }, { name: 'Bread', quantity: 4 }];
Come prima, un nuovo oggetto che rappresenta un elemento può essere aggiunto successivamente all’array:
cart.push({ name: 'Eggs', quantity: 12 });
Gli elementi della lista sono ora accessibili tramite il loro indice e il loro nome di proprietà:
console.log("Third item: " + cart[2].name);
console.log(cart[2].name + " quantity: " + cart[2].quantity);
L’output visualizzato sulla console dopo l’esecuzione di questo codice è:
third item: eggs Eggs quantity: 12
Le strutture di dati permettono al programmatore di mantenere il proprio codice molto più organizzato e più facile da mantenere, sia per l’autore originale che per altri programmatori del team. Inoltre, molti output delle funzioni JavaScript sono in tipi strutturati, che devono essere gestiti correttamente dal programmatore.
Operatori
Finora abbiamo praticamente visto solo come assegnare valori alle variabili appena create. Per quanto semplice, qualsiasi programma eseguirà diverse altre manipolazioni sui valori delle variabili. JavaScript offre diversi tipi di operatori che possono agire direttamente sul valore di una variabile o memorizzare il risultato dell’operazione in una nuova variabile.
La maggior parte degli operatori è orientata alle operazioni aritmetiche. Per aumentare la quantità di un elemento nella lista della spesa, per esempio, basta usare l’operatore di addizione +
:
item.quantity = item.quantity + 1;
Il seguente codice mostra il valore di item.quantity
prima e dopo l’aggiunta. Non confondete i ruoli del segno più nello codice. Le istruzioni di console.log
usano il segno più per combinare due stringhe.
let item = { name: 'Milk', quantity: 1 };
console.log("Item: " + item.name);
console.log("Quantity: " + item.quantity);
item.quantity = item.quantity + 1;
console.log("New quantity: " + item.quantity);
L’output visualizzato sulla console dopo aver eseguito questo codice è:
Item: Milk Quantity: 1 New quantity: 2
Si noti che il valore precedentemente memorizzato in item.quantity
viene utilizzato come operando dell’operazione di addizione: item.quantity = item.quantity + 1
. Solo al termine dell’operazione il valore in item.quantity
viene aggiornato con il risultato dell’operazione. Questo tipo di operazione aritmetica che coinvolge il valore corrente della variabile di destinazione è abbastanza comune, quindi esistono operatori abbreviati che consentono di scrivere la stessa operazione in un formato ridotto:
item.quantity += 1;
Anche le altre operazioni di base hanno operatori stenografici equivalenti:
-
a = a - b
è equivalente aa -= b
. -
a = a * b
è equivalente aa *= b
. -
a = a / b
è equivalente aa /= b
.
Per l’addizione e la sottrazione, è disponibile un terzo formato quando il secondo operando è solo un’unità:
-
a = a + 1
è equivalente aa++
. -
a = a - 1
è equivalente aa--
.
È possibile combinare più operatori nella stessa operazione e il risultato può essere memorizzato in una nuova variabile. Per esempio, la seguente istruzione calcola il prezzo totale di un articolo più un costo di spedizione:
let total = item.quantity * 9.99 + 3.15;
L’ordine in cui vengono eseguite le operazioni segue il tradizionale ordine di precedenza: prima vengono eseguite le operazioni di moltiplicazione e divisione, e solo dopo vengono eseguite le operazioni di addizione e sottrazione. Gli operatori con la stessa precedenza vengono eseguiti nell’ordine in cui compaiono nell’espressione, da sinistra a destra. Per sovrascrivere l’ordine di precedenza predefinito, puoi utilizzare le parentesi, come in a * (b + c)
.
In alcune situazioni, il risultato di un’operazione non ha nemmeno bisogno di essere memorizzato in una variabile. Questo è il caso in cui si desidera valutare il risultato di un’espressione all’interno di un’istruzione if
:
if ( item.quantiy % 2 == 0 )
{
console.log("Quantity for the item is even");
}
else
{
console.log("Quantity for the item is odd");
}
L’operatore %
(modulo) restituisce il resto della divisione del primo operando per il secondo operando. Nell’esempio, l’istruzione if
verifica se il resto della divisione di item.quantity
per 2
è uguale a zero, ovvero se item.quantity
è un multiplo di 2
.
Quando uno degli operandi dell’operatore +
è una stringa, gli altri operatori sono concatenati in stringhe e il risultato è una concatenazione di stringhe. Negli esempi precedenti, questo tipo di operazione è stato usato per concatenare stringhe e variabili nell’argomento dell’istruzione console.log
.
Questa conversione automatica potrebbe non essere il comportamento desiderato. Un valore fornito dall’utente in un campo del modulo, per esempio, potrebbe essere identificato come una stringa, ma in realtà è un valore numerico. In casi come questo, la variabile deve prima essere convertita in un numero con la funzione Number()
:
sum = Number(value1) + value2;
Inoltre, è importante verificare che l’utente abbia fornito un valore valido prima di procedere con l’operazione. In JavaScript, una variabile senza un valore assegnato contiene il valore null
. Questo permette al programmatore di usare una dichiarazione di decisione come if ( value1 == null )
per controllare se a una variabile è stato assegnato un valore, indipendentemente dal tipo di valore assegnato alla variabile.
Esercizi Guidati
-
Un array è una struttura di dati presente in diversi linguaggi di programmazione, alcuni dei quali permettono solo array con elementi dello stesso tipo. Nel caso di JavaScript, è possibile definire un array con elementi di tipo diverso?
-
Sulla base dell’esempio
let item = { name: 'Milk', quantity: 1 }
per un oggetto in una lista della spesa, come potrebbe essere dichiarato questo oggetto per includere il prezzo dell’articolo? -
In una sola riga di codice, quali sono i modi per aggiornare il valore di una variabile alla metà del suo valore attuale?
Esercizi Esplorativi
-
Nel seguente codice, quale valore verrà visualizzato nell’output della console?
var value = "Global"; { value = "Location"; } console.log(value);
-
Che cosa succede quando uno o più degli operandi coinvolti in un’operazione di moltiplicazione è una stringa?
-
Come è possibile rimuovere l’elemento
Eggs
dall’arraycart
dichiarato conlet cart = ['Milk', 'Bread', 'Eggs']
?
Sommario
Questa lezione spiega l’uso di base delle costanti e delle variabili in JavaScript. JavaScript è un linguaggio a tipizzazione dinamica, quindi il programmatore non ha bisogno di specificare il tipo di variabile prima di impostarla. Tuttavia, è importante conoscere i tipi primitivi del linguaggio per assicurare il corretto risultato delle operazioni di base. Inoltre, le strutture dati come gli array e gli oggetti combinano i tipi primitivi e permettono al programmatore di costruire variabili più complesse e composite. Questa lezione passa in rassegna i seguenti concetti e procedure:
-
Capire le costanti e le variabili
-
Ambito delle variabili
-
Dichiarare le variabili con
var
elet
-
Tipi primitivi
-
Operatori aritmetici
-
Array e oggetti
-
Coercizione e conversione dei tipi
Risposte agli Esercizi Guidati
-
Un array è una struttura di dati presente in diversi linguaggi di programmazione, alcuni dei quali permettono solo array con elementi dello stesso tipo. Nel caso di JavaScript, è possibile definire un array con elementi di tipo diverso?
Sì, in JavaScript è possibile definire array con elementi di diversi tipi primitivi, come stringhe e numeri.
-
Sulla base dell’esempio
let item = { name: 'Milk', quantity: 1 }
per un oggetto in una lista della spesa, come potrebbe essere dichiarato questo oggetto per includere il prezzo dell’articolo?let item = { name: 'Milk', quantity: 1, price: 4.99 };
-
In una sola riga di codice, quali sono i modi per aggiornare il valore di una variabile alla metà del suo valore attuale?
Si può usare la variabile stessa come operando,
value = value / 2
, o l’operatore abbreviato/=
:value /= 2
.
Risposte agli Esercizi Esplorativi
-
Nel seguente codice, quale valore verrà visualizzato nell’output della console?
var value = "Global"; { value = "Location"; } console.log(value);
Location
-
Che cosa succede quando uno o più degli operandi coinvolti in un’operazione di moltiplicazione è una stringa?
JavaScript assegnerà il valore
NaN
(Not a Number) al risultato, indicando che l’operazione non è valida. -
Come è possibile rimuovere l’elemento
Eggs
dall’arraycart
dichiarato conlet cart = ['Milk', 'Bread', 'Eggs']
?Gli array in JavaScript hanno il metodo
pop()
, che rimuove l’ultimo elemento della lista:cart.pop()
.