LA SINTASSI DI JavaScript: ISTRUZIONI DI CONTROLLO

Argomenti trattati: cicli e iterazioni nella sintassi JavaScript.

I Cicli

I cicli, detti anche strutture iterative, hanno una grande importanza in programmazione. Grazie ad essi è possibile eseguire, per mezzo di poche righe di codice, un numero potenzialmente infinito di istruzioni, che altrimenti richiederebbero, a seconda dei casi, decine, centinaia o addirittura migliaia di righe di codice. Sostanzialmente si tratta di "dire" al computer di ripetere un determinato numero di istruzioni fino a che non si verifica una certa condizione. In questo modo è possibile scrivere ciascuna istruzione una sola volta, indicando poi all'elaboratore - nel caso di JavaScript, all'interprete - per quante volte o fino a quando, tali istruzioni dovranno essere ripetute. Si è detto "per quante volte" e "fino a quando" proprio perché esistono fondamentalmente due tipi distinti di cicli; quelli detti a conteggio, che definiscono la propria esecuzione grazie a una variabile di tipo numerico che funge da contatore - ossia una variabile che, inizializzata all'inizio del ciclo, tiene poi il conto delle iterazioni compiute - e quelli condizionati, in cui invece la condizione di fine ciclo è il risultato di una qualsiasi espressione. In teoria, i cicli del primo tipo sono adatti a quei casi in cui il numero delle iterazioni da compiere è conoscibile a priori. È così in molti linguaggi di programmazione ma in JavaScript - e nei linguaggi da cui deriva, C/C++, Java - la distinzione è meno marcata, in quanto anche nei cicli del primo tipo è possibile avere il risultato di un'espressione come condizione di fine ciclo. I cicli si distinguono anche secondo altri criteri che però vedremo piú avanti. Dopo questa breve introduzione dell'argomento andiamo ad affrontare il ciclo forse piú duttile e flessibile che il linguaggio JavaScript mette a disposizione del programmatore: il ciclo for.

Il ciclo For

Il ciclo for appartiene al primo tipo, quello dei cicli a conteggio ma, come abbiamo detto, è possibile regolare la sua esecuzione anche in base a una condizione diversa, derivata da una qualsiasi espressione logica. Il ciclo for ha la seguente sintassi di base:

for (inizializzazione; condizione; incremento) {
  istruzioni;
}

Per inizializzazione si intende quella della variabile che funge da contatore del ciclo. La condizione è quella che determina fino a quando le istruzioni dovranno essere ripetute mentre l'incremento è quello che la variabile contatore subirà a ogni iterazione. Per mettere in pratica quanto detto, poniamo il caso di aver bisogno di un piccolo script che esegua il conto dei numeri da 1 a 10, visualizzandolo numero per numero in una finestra di dialogo. Il codice qui sotto mostra come risolvere il problema grazie all'utilizzo del ciclo for.

<html>
<title>Contatore da 1 a 10</title>
<head>
<script language="JavaScript">
<!--
     for (var i=1; i<=10; i++) {
       alert(i);
     }
-->
</script>
</head>

Esaminiamo nei dettagli la sintassi del ciclo for. Una particolarità interessante e molto utile di questo ciclo è che consente di dichiarare ed inizializzare una variabile direttamente al suo interno. La variabile i - i sta per index, indice, ed è una convenzione; la variabile può avere un nome qualsiasi che sia un identificatore valido per JavaScript - che terrà il conto delle iterazioni del ciclo, parte da 1 e il ciclo terminerà quando sarà arrivata a 10. Si presti particolare attenzione alla condizione di fine ciclo: un errore abbastanza frequente quando si ha a che fare con questo tipo di condizione è quello di scrivere i<10. Se si scrivesse cosí il ciclo si interromperebbe con un'iterazione di anticipo rispetto a quanto programmato. Per fare in modo che continui anche quando la variabile raggiunge quota 10 si dovrà dire: "continua fino a quando i è inferiore o uguale a 10". In questo modo, anche una volta arrivato a 10, il ciclo continuerà per un'altra volta l'esecuzione, visualizzando anche l'ultimo numero. L'istruzione di incremento viene scritta per ultima, utilizzando l'operatore di incremento ++. Si sarebbe anche potuto scrivere i=i+1 o anche utilizzare la forma abbreviata i+=1 ma è uso prevalente utilizzare, quando l'incremento è pari a 1, l'operatore ++. Il segno di punto e virgola (;) tra una istruzione e l'altra funge da separatore ed è obbligatorio, cosí come le parentesi tonde che racchiudono il tutto. Tutte le istruzioni racchiuse tra le parentesi graffe verranno ripetute fino a quando non si realizzerà la condizione di fine ciclo. Infine, è facile notare quanto l'utilizzo del ciclo for renda il codice estremamente sintetico. L'istruzione di visualizzazione alert(i); viene scritta una sola volta ma verrà mostrata all'utente per dieci volte. La variabile i assumerà di volta in volta il valore del numero corrente. L'unica alternativa a un ciclo sarebbe stata, per risolvere questo semplice problema, quella di scrivere dieci istruzioni alert, ciascuna con un numero da 1 a 10. Non sarebbe un problema insormontabile ma cosa accadrebbe se il conteggio, anziché fino a 10 dovesse arrivare fino a 1000 o 10000? Appare quindi evidente quanto i cicli siano indispensabili in programmazione.

Per eseguire il listato riportato nell'esempio cliccare sul pulsante qui sotto.

Incrementi diversi da 1

L'esempio precedente rappresenta solo il caso piú semplice in cui ci si può imbattere nell'utilizzo del ciclo for. In realtà, anche se è l'evenienza piú comune, una variabile contatore non deve necessariamente essere incrementata di una unità alla volta. La dimensione dell'incremento è a totale discrezione del programmatore. L'esempio qui sotto mostra l'utilizzo del ciclo for con un incremento pari a 10 per visualizzare le decine da 10 a 100.

<html>
<title>Contatore da 10 a 100</title>
<head>
<script language="JavaScript">
<!--
     for (var i=10; i<=100; i+=10) {
       alert(i);
     }
-->
</script>
</head>

Decremento di una variabile contatore

Cosí come può essere incrementata, ovviamente una variabile contatore può anche essere decrementata. Il contatore, cioè, può essere fatto "girare" al contrario. L'esempio seguente non è altro che il rovesciamento del primo esempio. Anziché contare i numeri da 1 a 10, li conta da 10 a 1, decrementando il contatore di una unità alla volta grazie all'operatore di decremento rappresentato dal simbolo --.

<html>
<title>Conto alla rovescia</title>
<head>
<script language="JavaScript">
<!--
     for (var i=10; i>0; i--) {
       alert(i);
     }
-->
</script>
</head>

For a conteggio e for condizionati

Come già anticipato nella breve introduzione ai cicli, in JavaScript un ciclo for, sebbene strutturato in maniera tale da essere adatto soprattutto per eseguire cicli a conteggio, può anche essere utilizzato, senza nessuna difficoltà, con condizioni diverse derivanti da una qualsiasi espressione logica. Si osservi attentamente il codice del seguente esempio:

<html>
<title>For condizionato</title>
<head>
<script language="JavaScript">
<!--
     var bool=false;
     for (var i=0; !bool; i++) {
        if (i<10) alert('i è ancora minore di 10: ' + i);
        else {
           alert('Ora i vale: ' + i);
           bool=true;
        }
     }
-->
</script>
</head>

In questo esempio la condizione è di tipo booleano; la variabile bool viene inizializzata a false prima del ciclo. Sebbene in questo caso, non diversamente da quelli precedenti, vi sia ugualmente la variabile contatore i che viene incrementata a ogni iterazione del ciclo, il controllo della condizione di fine ciclo non si basa piú su di essa ma sulla variabile booleana bool. Fino a che tale variabile resterà impostata a false il ciclo andrà avanti; quando la variabile i non sarà piú minore di 10 allora bool verrà impostata a true e il ciclo potrà terminare. La condizione può essere quindi "tradotta" cosí: "fino a che bool è falsa continua, quando diventa vera, esci".

Per avere una dimostrazione pratica di questo esempio premere il pulsante qui sotto.

Cicli for con parti mancanti

Ad inizio pagina si era accennato alla flessibilità del ciclo for. Oltre alle caratteristiche fin qui prese in esame dobbiamo aggiungerne un'altra molto importante che conferisce all'utilizzo di questo costrutto ulteriore duttilità: la possibilità di avere cicli for con parti mancanti. Per parti mancanti si intendono quelle presenti all'interno delle parentesi tonde. Come detto di norma al loro interno sono presenti tre parti fondamentali: inizializzazione, condizione, incremento. Ebbene, cosí come accade in C/C++ e Java, linguaggi "imparentati" con JavaScript, una qualsiasi di queste parti, o anche due di esse, possono essere omesse. Ovviamente, per evitare errori di esecuzione, bisogna avere ben presente quali parti del ciclo possono essere omesse senza compromettere il funzionamento dello stesso. Si veda il seguente esempio:

<html>
<title>Ciclo for con parti mancanti</title>
<head>
<script language="JavaScript">
<!--
     var i=1;
     for (; i<=10; i++) {
       alert(i);
     }
-->
</script>
</head>

In questo caso la parte inerente alla dichiarazione e all'inizializzazione della variabile contatore viene scritta prima del ciclo. L'esecuzione di questo, peraltro, si basa ugualmente sull'incremento di tale variabile, proprio come nel primo esempio. L'unica differenza è che la variabile viene inizializzata fuori dal ciclo. Da osservare che, anche se una o piú parti del ciclo vengono omesse, il segno del punto e virgola (;) dev'essere obbligatoriamente lasciato.

È anche possibile omettere un'altra delle due parti del ciclo, cosí come mostrato nel listato successivo:

<html>
<title>Ciclo for con parti mancanti</title>
<head>
<script language="JavaScript">
<!--
     var i=1;
     for (; i<=10;) {
       alert(i);
       i++;
     }
-->
</script>
</head>

In questo caso anche la parte riguardante l'incremento della variabile contatore viene omessa e spostata all'interno del ciclo. Dal punto di vista funzionale non cambia nulla. Anche se in questi due esempi non era necessario omettere alcune parti di for si possono dare casi in cui è piú comodo farlo; per esempio se la variabile contatore fosse derivata da calcoli precedenti al ciclo, sarebbe inutile reinizializzarla all'interno di esso con il valore che già ha. Risulterebbe piú comodo ometterne l'inizializzazione.

Anche la parte riguardante la condizione, non diversamente dalle altre due, può essere omessa, come nel listato seguente:

<html>
<title>Ciclo for con parti mancanti</title>
<head>
<script language="JavaScript">
<!--
     var i=1;
     for (;;) {
       if (i<=10) alert(i);
       i++;
     }
-->
</script>
</head>

In questo frammento di codice tutte e tre le parti del ciclo sono state omesse all'interno delle parentesi tonde, per essere solo spostate altrove. Il funzionamento del ciclo rimane identico. Se ci si fosse limitati a omettere tutte le parti di for senza trascriverle altrove si sarebbe dato luogo a un ciclo infinito di cui ci occuperemo tra poco.

Inizializzazione multipla e incremento/decremento multiplo

Abbiamo visto come sia possibile strutturare un ciclo for in maniera corretta pur omettendo alcune parti di esso; parallelamente è anche possibile strutturare cicli for che contengano al proprio interno piú di una inizializzazione e piú di un incremento o di un decremento. Vediamo come:

<html>
<title>Ciclo for inizializzazione e incremento multipli</title>
<head>
<script language="JavaScript">
<!--
     for (var i=0, j=1; i<=10; i++, j++) {
       alert('i vale:' + i + '\n' + 'j vale: ' + j);
     }
-->
</script>
</head>

Nell'esempio un ciclo for viene inizializzato con due variabili numeriche, i e j le quali vengono inizializzate rispettivamente a 0 e 1. Successivamente entrambe vengono incrementate di una unità e quando la variabile i raggiunge il valore di 10 il ciclo termina dopo aver mostrato di volta in volta i diversi valori delle due variabili. Da notare che quando si hanno inizializzazioni e incrementi multipli è obbligatorio aggiungere la virgola come separatore.

Condizioni multiple

Le condizioni non fanno eccezione e anch'esse possono essere multiple all'interno di un ciclo for. Questo è possibile grazie all'utilizzo degli operatori logici AND (&&) e OR (||) di cui si è trattato nel capitolo sugli operatori. L'esempio sotto mostra un ciclo for in cui tutte le parti sono multiple.

<html>
<title>Ciclo for a condizione multipla</title>
<head>
<script language="JavaScript">
<!--
     for (var i=0, j=15; i!=10 && j!=10; i++, j--) {
       alert('i vale:' + i + '\n' + 'j vale: ' + j);
     }
     alert('Valore di i alla fine del ciclo: ' + i + '\n' + 'Valore di j alla fine del ciclo: ' + j);
-->
</script>
</head>

Osservando attentamente il codice d'esempio si potrà notare come per JavaScript non sia un problema "mischiare" operatori di incremento e di decremento; la condizione di fine ciclo è che almeno una delle due variabili i e j debba essere uguale a 10 ma mentre i parte da zero j parte da 15. Dunque si dovrà incrementare la prima e decrementare la seconda. Quando una delle due sarà uguale a dieci il ciclo terminerà. Ovviamente, nel caso specifico, sarà j ad arrivare a 10 per prima, essendo il suo valore piú prossimo a tale numero.

Per provare quest'esempio cliccare il pulsante qui sotto.

Cicli infiniti

Un errore non cosí infrequente in cui si può incorrere nel definire un ciclo è quello di renderlo infinito. Per infinito si intende un ciclo che ha come condizione di fine una condizione che non potrà mai verificarsi. In tal caso il ciclo andrà avanti all'infinito e l'unico modo di fermarlo sarà quello di chiudere forzatamente il programma. Un banale esempio di ciclo infinito può essere questo:

<html>
<title>Ciclo infinito</title>
<head>
<script language="JavaScript">
<!--
     for (var i=1; i<=10;) {
       alert(i);
     }
-->
</script>
</head>

Il ciclo d'esempio è infinito perché contiene un grossolano errore logico; manca infatti la parte del ciclo che dovrebbe incrementare la variabile contatore, di conseguenza, rimanendo quest'ultima sempre uguale a 1 non potrà mai soddisfare la condizione di fine ciclo che richiederebbe invece che essa diventasse uguale a 10. Un ciclo del genere continuerebbe a mostrare all'infinito una finestra di dialogo con il numero 1.

Cicli for annidati

Come if, switch e gli altri cicli che vedremo in seguito anche for può essere usato a piú livelli di annidamento. Poniamo il caso di aver bisogno di "scorrere" tutte le coordinate x e y da 0 a 9 su un'ipotetica griglia numerica in cui le coordinate si intersecano come nel gioco della battaglia navale: per farlo dovremmo annidare due cicli for come nell'esempio qui sotto:

<html>
<title>Cicli for annidati</title>
<head>
<script language="JavaScript">
<!--
     var stringa='';
     for (var x=0; x<10; x++) {
       for (var y=0; y<10; y++) {
         stringa+='(' + x + ',' + y + ')' + ' ';
       }
       stringa+='\n';
     }
     alert(stringa);
-->
</script>
</head>

Nell'esempio una variabile stringa viene inizializzata come vuota fuori dal ciclo; durante l'esecuzione dello stesso viene riempita con i valori progressivi delle coordinate x e y messi tra parentesi tonde e separati da una virgola, e infine mostrata all'utente in una finestra di dialogo. Il primo ciclo for, quello piú esterno, contiene il secondo ciclo che proseguirà la sua esecuzione fino a che non sarà arrivato a 9. Durante questo periodo riempirà la stringa con i valori delle coordinate della riga 0 e quelle delle colonne da 0 a 9, dopodiché il controllo tornerà al ciclo piú esterno per continuare fino a che anche le coordinate della riga non saranno arrivate a 9. Da ciò si deduce che il ciclo piú interno scorre piú velocemente di quello piú esterno. Questo metodo di scorrimento tornerà molto utile quando si dovranno scorrere gli elementi di un array multidimensionale, detto anche matrice.

Conclusioni

Abbiamo visto in quanti e quali modi possa essere usato il ciclo for. Dovrebbe essere scontato che, oltre a poter annidare altri cicli dello stesso tipo al suo interno, for è in grado di contenere qualsiasi tipo di istruzione, incluse quelle condizionali if e switch. A loro volta, inoltre, una if o una switch contenute all'interno di un ciclo for o di altro tipo, possono contenere altri cicli che a loro volta possono contenere altre istruzioni e cosí via. In JavaScript esiste un altro ciclo for ed è for... in che però viene utilizzato con gli oggetti del linguaggio e verrà trattato piú in là. Quando il ciclo for risulterà ben chiaro si potrà passare alla trattazione degli altri cicli, a cominciare dal ciclo while.


Torna all'inizio | Home